xref: /trunk/main/sw/source/core/doc/doc.cxx (revision 46d9d397)
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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <doc.hxx>
28 #include <UndoManager.hxx>
29 #include <hintids.hxx>
30 #include <tools/shl.hxx>
31 #include <tools/globname.hxx>
32 #include <svx/svxids.hrc>
33 #include <com/sun/star/i18n/WordType.hdl>
34 #include <com/sun/star/i18n/ForbiddenCharacters.hdl>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <com/sun/star/beans/NamedValue.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
39 #include <com/sun/star/document/XDocumentProperties.hpp>
40 #include <comphelper/processfactory.hxx>
41 #include <tools/urlobj.hxx>
42 #include <tools/poly.hxx>
43 #include <tools/multisel.hxx>
44 #include <rtl/ustring.hxx>
45 #include <vcl/virdev.hxx>
46 #include <svl/itemiter.hxx>
47 #include <svl/poolitem.hxx>
48 #include <unotools/syslocale.hxx>
49 #include <sfx2/printer.hxx>
50 #include <editeng/keepitem.hxx>
51 #include <editeng/cscoitem.hxx>
52 #include <editeng/brkitem.hxx>
53 #include <sfx2/linkmgr.hxx>
54 #include <editeng/forbiddencharacterstable.hxx>
55 #include <svx/svdmodel.hxx>
56 #include <editeng/pbinitem.hxx>
57 #include <unotools/charclass.hxx>
58 #include <unotools/localedatawrapper.hxx>
59 #include <swatrset.hxx>
60 #include <swmodule.hxx>
61 #include <fmtpdsc.hxx>
62 #include <fmtanchr.hxx>
63 #include <fmtrfmrk.hxx>
64 #include <fmtinfmt.hxx>
65 #include <fmtfld.hxx>
66 #include <txtfld.hxx>
67 #include <dbfld.hxx>
68 #include <txtinet.hxx>
69 #include <txtrfmrk.hxx>
70 #include <frmatr.hxx>
71 #include <linkenum.hxx>
72 #include <errhdl.hxx>
73 #include <pagefrm.hxx>
74 #include <rootfrm.hxx>
75 #include <swtable.hxx>
76 #include <pam.hxx>
77 #include <ndtxt.hxx>
78 #include <swundo.hxx>		// for the UndoIds
79 #include <UndoCore.hxx>
80 #include <UndoInsert.hxx>
81 #include <UndoSplitMove.hxx>
82 #include <UndoTable.hxx>
83 #include <pagedesc.hxx>		//DTor
84 #include <breakit.hxx>
85 #include <ndole.hxx>
86 #include <ndgrf.hxx>
87 #include <rolbck.hxx>		// Undo-Attr
88 #include <doctxm.hxx>		// for the directories
89 #include <grfatr.hxx>
90 #include <poolfmt.hxx>		// PoolTemplate ID's
91 #include <mvsave.hxx>		// for server functionality
92 #include <SwGrammarMarkUp.hxx>
93 #include <scriptinfo.hxx>
94 #include <acorrect.hxx>		// AutoCorrect
95 #include <mdiexp.hxx>	   	// status display
96 #include <docstat.hxx>
97 #include <docary.hxx>
98 #include <redline.hxx>
99 #include <fldupde.hxx>
100 #include <swbaslnk.hxx>
101 #include <printdata.hxx>
102 #include <cmdid.h>              // for the dflt - Printer in SetJob
103 #include <statstr.hrc>      	// StatLine string
104 #include <comcore.hrc>
105 #include <SwUndoTOXChange.hxx>
106 #include <SwUndoFmt.hxx>
107 #include <unocrsr.hxx>
108 #include <docsh.hxx>
109 #include <viewopt.hxx>
110 #include <docfld.hxx>           // _SetGetExpFld
111 #include <docufld.hxx>          // SwPostItField
112 #include <viewsh.hxx>
113 #include <shellres.hxx>
114 #include <txtfrm.hxx>
115 #include <attrhint.hxx>
116 #include <wdocsh.hxx>           // SwWebDocShell
117 #include <prtopt.hxx>           // SwPrintOptions
118 #include <vector>
119 #include <map>
120 #include <osl/diagnose.h>
121 #include <osl/interlck.h>
122 #include <vbahelper/vbaaccesshelper.hxx>
123 #include "switerator.hxx"
124 #include <layouter.hxx>
125 #include <drawdoc.hxx>
126 
127 using namespace ::com::sun::star;
128 using ::rtl::OUString;
129 
130 
131 // Page descriptors
132 SV_IMPL_PTRARR(SwPageDescs,SwPageDescPtr);
133 // Directories
SV_IMPL_PTRARR(SwTOXTypes,SwTOXTypePtr)134 SV_IMPL_PTRARR( SwTOXTypes, SwTOXTypePtr )
135 // Field types
136 SV_IMPL_PTRARR( SwFldTypes, SwFldTypePtr)
137 
138 /** IInterface
139 */
140 sal_Int32 SwDoc::acquire()
141 {
142 	OSL_ASSERT(mReferenceCount >= 0 && "Negative reference count detected! This is a sign for unbalanced acquire/release calls.");
143 	return osl_incrementInterlockedCount(&mReferenceCount);
144 }
145 
release()146 sal_Int32 SwDoc::release()
147 {
148 	OSL_PRECOND(mReferenceCount >= 1, "Object is already released! Releasing it again leads to a negative reference count.");
149 	return osl_decrementInterlockedCount(&mReferenceCount);
150 }
151 
getReferenceCount() const152 sal_Int32 SwDoc::getReferenceCount() const
153 {
154 	OSL_ASSERT(mReferenceCount >= 0 && "Negative reference count detected! This is a sign for unbalanced acquire/release calls.");
155 	return mReferenceCount;
156 }
157 
158 /** IDocumentSettingAccess
159 */
get(DocumentSettingId id) const160 bool SwDoc::get(/*[in]*/ DocumentSettingId id) const
161 {
162     switch (id)
163     {
164         // COMPATIBILITY FLAGS START
165         case PARA_SPACE_MAX: return mbParaSpaceMax; //(n8Dummy1 & DUMMY_PARASPACEMAX);
166         case PARA_SPACE_MAX_AT_PAGES: return mbParaSpaceMaxAtPages; //(n8Dummy1 & DUMMY_PARASPACEMAX_AT_PAGES);
167         case TAB_COMPAT: return mbTabCompat; //(n8Dummy1 & DUMMY_TAB_COMPAT);
168         case ADD_FLY_OFFSETS: return mbAddFlyOffsets; //(n8Dummy2 & DUMMY_ADD_FLY_OFFSETS);
169         case ADD_EXT_LEADING: return mbAddExternalLeading; //(n8Dummy2 & DUMMY_ADD_EXTERNAL_LEADING);
170         case USE_VIRTUAL_DEVICE: return mbUseVirtualDevice; //(n8Dummy1 & DUMMY_USE_VIRTUAL_DEVICE);
171         case USE_HIRES_VIRTUAL_DEVICE: return mbUseHiResolutionVirtualDevice; //(n8Dummy2 & DUMMY_USE_HIRES_VIR_DEV);
172         case OLD_NUMBERING: return mbOldNumbering;
173         case OLD_LINE_SPACING: return mbOldLineSpacing;
174         case ADD_PARA_SPACING_TO_TABLE_CELLS: return mbAddParaSpacingToTableCells;
175         case USE_FORMER_OBJECT_POS: return mbUseFormerObjectPos;
176         case USE_FORMER_TEXT_WRAPPING: return mbUseFormerTextWrapping;
177         case CONSIDER_WRAP_ON_OBJECT_POSITION: return mbConsiderWrapOnObjPos;
178         case DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: return mbDoNotJustifyLinesWithManualBreak;
179         case IGNORE_FIRST_LINE_INDENT_IN_NUMBERING: return mbIgnoreFirstLineIndentInNumbering;
180         case OUTLINE_LEVEL_YIELDS_OUTLINE_RULE: return mbOutlineLevelYieldsOutlineRule;
181 	    case TABLE_ROW_KEEP: return mbTableRowKeep;
182 	    case IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION: return mbIgnoreTabsAndBlanksForLineCalculation;
183 	    case DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE: return mbDoNotCaptureDrawObjsOnPage;
184         // --> OD 2006-08-25 #i68949#
185         case CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME: return mbClipAsCharacterAnchoredWriterFlyFrames;
186         // <--
187         case UNIX_FORCE_ZERO_EXT_LEADING: return mbUnixForceZeroExtLeading;
188         case USE_OLD_PRINTER_METRICS: return mbOldPrinterMetrics;
189         case TABS_RELATIVE_TO_INDENT : return mbTabRelativeToIndent;
190         case PROTECT_FORM: return mbProtectForm;
191         // --> OD 2008-06-05 #i89181#
192         case TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST: return mbTabAtLeftIndentForParagraphsInList;
193         // <--
194          // COMPATIBILITY FLAGS END
195 
196         case BROWSE_MODE: return mbLastBrowseMode; // Attention: normally the ViewShell has to be asked!
197         case HTML_MODE: return mbHTMLMode;
198         case GLOBAL_DOCUMENT: return mbIsGlobalDoc;
199         case GLOBAL_DOCUMENT_SAVE_LINKS: return mbGlblDocSaveLinks;
200         case LABEL_DOCUMENT: return mbIsLabelDoc;
201         case PURGE_OLE: return mbPurgeOLE;
202         case KERN_ASIAN_PUNCTUATION: return mbKernAsianPunctuation;
203         case DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT: return mbDoNotResetParaAttrsForNumFont;
204         case MATH_BASELINE_ALIGNMENT: return mbMathBaselineAlignment;
205         default:
206             ASSERT(false, "Invalid setting id");
207     }
208     return false;
209 }
210 
set(DocumentSettingId id,bool value)211 void SwDoc::set(/*[in]*/ DocumentSettingId id, /*[in]*/ bool value)
212 {
213     switch (id)
214     {
215         // COMPATIBILITY FLAGS START
216         case PARA_SPACE_MAX:
217             mbParaSpaceMax = value;
218             break;
219         case PARA_SPACE_MAX_AT_PAGES:
220             mbParaSpaceMaxAtPages = value;
221             break;
222         case TAB_COMPAT:
223             mbTabCompat = value;
224             break;
225         case ADD_FLY_OFFSETS:
226             mbAddFlyOffsets = value;
227             break;
228         case ADD_EXT_LEADING:
229             mbAddExternalLeading = value;
230             break;
231         case USE_VIRTUAL_DEVICE:
232             mbUseVirtualDevice = value;
233             break;
234         case USE_HIRES_VIRTUAL_DEVICE:
235             mbUseHiResolutionVirtualDevice = value;
236             break;
237         case OLD_NUMBERING:
238             if (mbOldNumbering != value)
239             {
240                 mbOldNumbering = value;
241 
242                 const SwNumRuleTbl& rNmTbl = GetNumRuleTbl();
243                 for( sal_uInt16 n = 0; n < rNmTbl.Count(); ++n )
244                     rNmTbl[n]->SetInvalidRule(sal_True);
245 
246                 UpdateNumRule();
247 
248                 if (pOutlineRule)
249                 {
250                     pOutlineRule->Validate();
251                     // counting of phantoms depends on <IsOldNumbering()>
252                     pOutlineRule->SetCountPhantoms( !mbOldNumbering );
253                 }
254             }
255             break;
256         case OLD_LINE_SPACING:
257             mbOldLineSpacing = value;
258             break;
259         case ADD_PARA_SPACING_TO_TABLE_CELLS:
260             mbAddParaSpacingToTableCells = value;
261             break;
262         case USE_FORMER_OBJECT_POS:
263             mbUseFormerObjectPos = value;
264             break;
265         case USE_FORMER_TEXT_WRAPPING:
266             mbUseFormerTextWrapping = value;
267             break;
268         case CONSIDER_WRAP_ON_OBJECT_POSITION:
269             mbConsiderWrapOnObjPos = value;
270             break;
271         case DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK:
272             mbDoNotJustifyLinesWithManualBreak = value;
273             break;
274         case IGNORE_FIRST_LINE_INDENT_IN_NUMBERING:
275             mbIgnoreFirstLineIndentInNumbering = value;
276             break;
277 
278         case OUTLINE_LEVEL_YIELDS_OUTLINE_RULE:
279             mbOutlineLevelYieldsOutlineRule = value;
280             break;
281 
282         case TABLE_ROW_KEEP:
283             mbTableRowKeep = value;
284             break;
285 
286         case IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION:
287             mbIgnoreTabsAndBlanksForLineCalculation = value;
288             break;
289 
290         case DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE:
291             mbDoNotCaptureDrawObjsOnPage = value;
292             break;
293 
294         case CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME:
295             mbClipAsCharacterAnchoredWriterFlyFrames = value;
296             break;
297 
298         case UNIX_FORCE_ZERO_EXT_LEADING:
299             mbUnixForceZeroExtLeading = value;
300             break;
301 
302         case PROTECT_FORM:
303             mbProtectForm = value;
304             break;
305 
306         case USE_OLD_PRINTER_METRICS:
307             mbOldPrinterMetrics = value;
308             break;
309 
310         case TABS_RELATIVE_TO_INDENT:
311             mbTabRelativeToIndent = value;
312         break;
313 
314         case TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST:
315             mbTabAtLeftIndentForParagraphsInList = value;
316         break;
317 
318         // COMPATIBILITY FLAGS END
319 
320         case BROWSE_MODE: //can be used temporary (load/save) when no ViewShell is available
321             mbLastBrowseMode = value;
322             break;
323         case HTML_MODE:
324             mbHTMLMode = value;
325             break;
326         case GLOBAL_DOCUMENT:
327             mbIsGlobalDoc = value;
328             break;
329         case GLOBAL_DOCUMENT_SAVE_LINKS:
330             mbGlblDocSaveLinks = value;
331             break;
332         case LABEL_DOCUMENT:
333             mbIsLabelDoc = value;
334             break;
335         case PURGE_OLE:
336             mbPurgeOLE = value;
337             break;
338         case KERN_ASIAN_PUNCTUATION:
339             mbKernAsianPunctuation = value;
340             break;
341         case DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT:
342             mbDoNotResetParaAttrsForNumFont = value;
343             break;
344         case MATH_BASELINE_ALIGNMENT:
345             mbMathBaselineAlignment = value;
346             break;
347         default:
348             ASSERT(false, "Invalid setting id");
349     }
350 }
351 
352 const i18n::ForbiddenCharacters*
getForbiddenCharacters(sal_uInt16 nLang,bool bLocaleData) const353     SwDoc::getForbiddenCharacters(/*[in]*/ sal_uInt16 nLang, /*[in]*/ bool bLocaleData ) const
354 {
355     const i18n::ForbiddenCharacters* pRet = 0;
356     if( xForbiddenCharsTable.isValid() )
357         pRet = xForbiddenCharsTable->GetForbiddenCharacters( nLang, sal_False );
358     if( bLocaleData && !pRet && pBreakIt )
359         pRet = &pBreakIt->GetForbidden( (LanguageType)nLang );
360     return pRet;
361 }
362 
setForbiddenCharacters(sal_uInt16 nLang,const com::sun::star::i18n::ForbiddenCharacters & rFChars)363 void SwDoc::setForbiddenCharacters(/*[in]*/ sal_uInt16 nLang,
364                                    /*[in]*/ const com::sun::star::i18n::ForbiddenCharacters& rFChars )
365 {
366     if( !xForbiddenCharsTable.isValid() )
367     {
368         uno::Reference<
369             lang::XMultiServiceFactory > xMSF =
370                                     ::comphelper::getProcessServiceFactory();
371         xForbiddenCharsTable = new SvxForbiddenCharactersTable( xMSF );
372     }
373     xForbiddenCharsTable->SetForbiddenCharacters( nLang, rFChars );
374     if( pDrawModel )
375     {
376         pDrawModel->SetForbiddenCharsTable( xForbiddenCharsTable );
377         if( !mbInReading )
378             pDrawModel->ReformatAllTextObjects();
379     }
380 
381     SwRootFrm* pTmpRoot = GetCurrentLayout();
382 	if( pTmpRoot && !mbInReading )
383     {
384         pTmpRoot->StartAllAction();
385 		std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
386 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(), std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE));
387         pTmpRoot->EndAllAction();
388     }//swmod 080310
389     SetModified();
390 }
391 
getForbiddenCharacterTable()392 vos::ORef<SvxForbiddenCharactersTable>& SwDoc::getForbiddenCharacterTable()
393 {
394     if( !xForbiddenCharsTable.isValid() )
395     {
396         uno::Reference<
397             lang::XMultiServiceFactory > xMSF =
398                                     ::comphelper::getProcessServiceFactory();
399         xForbiddenCharsTable = new SvxForbiddenCharactersTable( xMSF );
400     }
401     return xForbiddenCharsTable;
402 }
403 
getForbiddenCharacterTable() const404 const vos::ORef<SvxForbiddenCharactersTable>& SwDoc::getForbiddenCharacterTable() const
405 {
406     return xForbiddenCharsTable;
407 }
408 
getLinkUpdateMode(bool bGlobalSettings) const409 sal_uInt16 SwDoc::getLinkUpdateMode( /*[in]*/bool bGlobalSettings ) const
410 {
411     sal_uInt16 nRet = nLinkUpdMode;
412     if( bGlobalSettings && GLOBALSETTING == nRet )
413         nRet = SW_MOD()->GetLinkUpdMode(get(IDocumentSettingAccess::HTML_MODE));
414     return nRet;
415 }
416 
setLinkUpdateMode(sal_uInt16 eMode)417 void SwDoc::setLinkUpdateMode( /*[in]*/sal_uInt16 eMode )
418 {
419     nLinkUpdMode = eMode;
420 }
421 
getFieldUpdateFlags(bool bGlobalSettings) const422 SwFldUpdateFlags SwDoc::getFieldUpdateFlags( /*[in]*/bool bGlobalSettings ) const
423 {
424     SwFldUpdateFlags eRet = eFldUpdMode;
425     if( bGlobalSettings && AUTOUPD_GLOBALSETTING == eRet )
426         eRet = SW_MOD()->GetFldUpdateFlags(get(IDocumentSettingAccess::HTML_MODE));
427     return eRet;
428 }
429 
setFieldUpdateFlags(SwFldUpdateFlags eMode)430 void SwDoc::setFieldUpdateFlags(/*[in]*/SwFldUpdateFlags eMode )
431 {
432     eFldUpdMode = eMode;
433 }
434 
getCharacterCompressionType() const435 SwCharCompressType SwDoc::getCharacterCompressionType() const
436 {
437     return eChrCmprType;
438 }
439 
setCharacterCompressionType(SwCharCompressType n)440 void SwDoc::setCharacterCompressionType( /*[in]*/SwCharCompressType n )
441 {
442     if( eChrCmprType != n )
443     {
444         eChrCmprType = n;
445         if( pDrawModel )
446         {
447             pDrawModel->SetCharCompressType( static_cast<sal_uInt16>(n) );
448             if( !mbInReading )
449                 pDrawModel->ReformatAllTextObjects();
450         }
451 
452 		SwRootFrm* pTmpRoot = GetCurrentLayout();
453 		if( pTmpRoot && !mbInReading )
454         {
455 			pTmpRoot->StartAllAction();
456 			std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
457 			std::for_each( aAllLayouts.begin(), aAllLayouts.end(), std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE));
458 			pTmpRoot->EndAllAction();
459 		}//swmod 080310
460         SetModified();
461     }
462 }
463 
464 /** IDocumentDeviceAccess
465 */
getPrinter(bool bCreate) const466 SfxPrinter* SwDoc::getPrinter(/*[in]*/ bool bCreate ) const
467 {
468     SfxPrinter* pRet = 0;
469     if ( !bCreate || pPrt )
470         pRet = pPrt;
471     else
472         pRet = &CreatePrinter_();
473 
474     return pRet;
475 }
476 
setPrinter(SfxPrinter * pP,bool bDeleteOld,bool bCallPrtDataChanged)477 void SwDoc::setPrinter(/*[in]*/ SfxPrinter *pP,/*[in]*/ bool bDeleteOld,/*[in]*/ bool bCallPrtDataChanged )
478 {
479     if ( pP != pPrt )
480     {
481         if ( bDeleteOld )
482             delete pPrt;
483         pPrt = pP;
484 
485         // our printer should always use TWIP. Don't rely on this being set in ViewShell::InitPrt, there
486         // are situations where this isn't called.
487         // #i108712# / 2010-02-26 / frank.schoenheit@sun.com
488         if ( pPrt )
489         {
490             MapMode aMapMode( pPrt->GetMapMode() );
491             aMapMode.SetMapUnit( MAP_TWIP );
492             pPrt->SetMapMode( aMapMode );
493         }
494 
495         if ( pDrawModel && !get( IDocumentSettingAccess::USE_VIRTUAL_DEVICE ) )
496             pDrawModel->SetRefDevice( pPrt );
497     }
498 
499     if ( bCallPrtDataChanged &&
500          // --> FME 2005-01-21 #i41075# Do not call PrtDataChanged() if we do not
501          // use the printer for formatting:
502          !get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) )
503         // <--
504         PrtDataChanged();
505 }
506 
getVirtualDevice(bool bCreate) const507 VirtualDevice* SwDoc::getVirtualDevice(/*[in]*/ bool bCreate ) const
508 {
509     VirtualDevice* pRet = 0;
510     if ( !bCreate || pVirDev )
511         pRet = pVirDev;
512     else
513         pRet = &CreateVirtualDevice_();
514 
515     return pRet;
516 }
517 
setVirtualDevice(VirtualDevice * pVd,bool bDeleteOld,bool)518 void SwDoc::setVirtualDevice(/*[in]*/ VirtualDevice* pVd,/*[in]*/ bool bDeleteOld, /*[in]*/ bool )
519 {
520     if ( pVirDev != pVd )
521     {
522         if ( bDeleteOld )
523             delete pVirDev;
524         pVirDev = pVd;
525 
526         if ( pDrawModel && get( IDocumentSettingAccess::USE_VIRTUAL_DEVICE ) )
527             pDrawModel->SetRefDevice( pVirDev );
528     }
529 }
530 
getReferenceDevice(bool bCreate) const531 OutputDevice* SwDoc::getReferenceDevice(/*[in]*/ bool bCreate ) const
532 {
533     OutputDevice* pRet = 0;
534     if ( !get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) )
535     {
536         pRet = getPrinter( bCreate );
537 
538         if ( bCreate && !pPrt->IsValid() )
539         {
540             pRet = getVirtualDevice( sal_True );
541         }
542     }
543     else
544     {
545         pRet = getVirtualDevice( bCreate );
546     }
547 
548     return pRet;
549 }
550 
setReferenceDeviceType(bool bNewVirtual,bool bNewHiRes)551 void SwDoc::setReferenceDeviceType(/*[in]*/ bool bNewVirtual,/*[in]*/ bool bNewHiRes )
552 {
553     if ( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) != bNewVirtual ||
554          get(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE) != bNewHiRes )
555     {
556         if ( bNewVirtual )
557         {
558             VirtualDevice* pMyVirDev = getVirtualDevice( true );
559             if ( !bNewHiRes )
560                 pMyVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE06 );
561             else
562                 pMyVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_MSO1 );
563 
564             if( pDrawModel )
565                 pDrawModel->SetRefDevice( pMyVirDev );
566         }
567         else
568         {
569             // --> FME 2005-01-21 #i41075#
570             // We have to take care that a printer exists before calling
571             // PrtDataChanged() in order to prevent that PrtDataChanged()
572             // triggers this funny situation:
573             // getReferenceDevice()->getPrinter()->CreatePrinter_()
574             // ->setPrinter()-> PrtDataChanged()
575             SfxPrinter* pPrinter = getPrinter( true );
576             // <--
577             if( pDrawModel )
578                 pDrawModel->SetRefDevice( pPrinter );
579         }
580 
581         set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, bNewVirtual );
582         set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, bNewHiRes );
583         PrtDataChanged();
584         SetModified();
585     }
586 }
587 
getJobsetup() const588 const JobSetup* SwDoc::getJobsetup() const
589 {
590     return pPrt ? &pPrt->GetJobSetup() : 0;
591 }
592 
setJobsetup(const JobSetup & rJobSetup)593 void SwDoc::setJobsetup(/*[in]*/ const JobSetup &rJobSetup )
594 {
595     sal_Bool bCheckPageDescs = 0 == pPrt;
596     sal_Bool bDataChanged = sal_False;
597 
598     if ( pPrt )
599     {
600         if ( pPrt->GetName() == rJobSetup.GetPrinterName() )
601         {
602             if ( pPrt->GetJobSetup() != rJobSetup )
603             {
604                 pPrt->SetJobSetup( rJobSetup );
605                 bDataChanged = sal_True;
606             }
607         }
608         else
609             delete pPrt, pPrt = 0;
610     }
611 
612     if( !pPrt )
613     {
614         // the ItemSet will be deleted by Sfx!
615         SfxItemSet *pSet = new SfxItemSet( GetAttrPool(),
616                         FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER,
617                         SID_HTML_MODE, SID_HTML_MODE,
618                         SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
619                         SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC,
620                         0 );
621         SfxPrinter *p = new SfxPrinter( pSet, rJobSetup );
622         if ( bCheckPageDescs )
623             setPrinter( p, true, true );
624         else
625         {
626             pPrt = p;
627             bDataChanged = sal_True;
628         }
629     }
630     if ( bDataChanged && !get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) )
631         PrtDataChanged();
632 }
633 
getPrintData() const634 const SwPrintData & SwDoc::getPrintData() const
635 {
636     if(!pPrtData)
637     {
638         SwDoc * pThis = const_cast< SwDoc * >(this);
639         pThis->pPrtData = new SwPrintData;
640 
641         // SwPrintData should be initialized from the configuration,
642         // the respective config item is implemented by SwPrintOptions which
643         // is also derived from SwPrintData
644         const SwDocShell *pDocSh = GetDocShell();
645         DBG_ASSERT( pDocSh, "pDocSh is 0, can't determine if this is a WebDoc or not" );
646         bool bWeb = 0 != dynamic_cast< const SwWebDocShell * >(pDocSh);
647         SwPrintOptions aPrintOptions( bWeb );
648         *pThis->pPrtData = aPrintOptions;
649     }
650     return *pPrtData;
651 }
652 
setPrintData(const SwPrintData & rPrtData)653 void SwDoc::setPrintData(/*[in]*/ const SwPrintData& rPrtData )
654 {
655     if(!pPrtData)
656         pPrtData = new SwPrintData;
657     *pPrtData = rPrtData;
658 }
659 
660 /** Implementations the next Interface here
661 */
662 
663 /*
664  * Document editing (Doc-SS) to fill the documents
665  * by the RTF parser and for the EditShell.
666  */
ChgDBData(const SwDBData & rNewData)667 void SwDoc::ChgDBData(const SwDBData& rNewData)
668 {
669 	if( rNewData != aDBData )
670 	{
671 		aDBData = rNewData;
672 		SetModified();
673 	}
674 	GetSysFldType(RES_DBNAMEFLD)->UpdateFlds();
675 }
676 
SplitNode(const SwPosition & rPos,bool bChkTableStart)677 bool SwDoc::SplitNode( const SwPosition &rPos, bool bChkTableStart )
678 {
679 	SwCntntNode *pNode = rPos.nNode.GetNode().GetCntntNode();
680 	if(0 == pNode)
681 		return false;
682 
683 	{
684 		// Bug 26675:	Sent DataChanged before deletion, then you can
685 		//		still notice which objects are in the range.
686 		//		After that the objects can be before/after the position.
687 		SwDataChanged aTmp( this, rPos, 0 );
688 	}
689 
690 	SwUndoSplitNode* pUndo = 0;
691     if (GetIDocumentUndoRedo().DoesUndo())
692     {
693         GetIDocumentUndoRedo().ClearRedo();
694 		// insert the Undo object, currently only in TextNode
695 		if( pNode->IsTxtNode() )
696         {
697             pUndo = new SwUndoSplitNode( this, rPos, bChkTableStart );
698             GetIDocumentUndoRedo().AppendUndo(pUndo);
699         }
700     }
701 
702 	//JP 28.01.97:	Special case for SplitNode at table start:
703 	//		Are they at Doc/Fly/Footer/..-Start or directly
704 	//		behind a table, then insert a paragraph before it
705 	if( bChkTableStart && !rPos.nContent.GetIndex() && pNode->IsTxtNode() )
706 	{
707 		sal_uLong nPrevPos = rPos.nNode.GetIndex() - 1;
708 		const SwTableNode* pTblNd;
709 		const SwNode* pNd = GetNodes()[ nPrevPos ];
710 		if( pNd->IsStartNode() &&
711 			SwTableBoxStartNode == ((SwStartNode*)pNd)->GetStartNodeType() &&
712 			0 != ( pTblNd = GetNodes()[ --nPrevPos ]->GetTableNode() ) &&
713 			((( pNd = GetNodes()[ --nPrevPos ])->IsStartNode() &&
714 			   SwTableBoxStartNode != ((SwStartNode*)pNd)->GetStartNodeType() )
715                || ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsTableNode() )
716 			   || pNd->IsCntntNode() ))
717 		{
718 			if( pNd->IsCntntNode() )
719 			{
720 				//JP 30.04.99 Bug 65660:
721 				// Outside of the normal BodyArea there are no page breaks,
722 				// therefore this is no valid condition for inserting a paragraph
723 				if( nPrevPos < GetNodes().GetEndOfExtras().GetIndex() )
724 					pNd = 0;
725 				else
726 				{
727 					// only when the table has breaks!
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 					// only move the page break/page style inside the BodyArea
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 		// now move all 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 
AppendTxtNode(SwPosition & rPos)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 		// now a node can be created!
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 
InsertString(const SwPaM & rRg,const String & rStr,const enum InsertFlags nInsertMode)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 )					// take it to AutoCorrect
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 	{			// if Undo and Grouping is enabled, then all is different!
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 			// if CanGrouping() is returning sal_True, then all is already done
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 
_InsNoTxtNode(const SwPosition & rPos,SwNoTxtNode * pNode,const SfxItemSet * pFlyAttrSet,const SfxItemSet * pGrfAttrSet,SwFrmFmt * pFrmFmt)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 
Insert(const SwPaM & rRg,const String & rGrfName,const String & rFltName,const Graphic * pGraphic,const SfxItemSet * pFlyAttrSet,const SfxItemSet * pGrfAttrSet,SwFrmFmt * pFrmFmt)956 SwFlyFrmFmt* SwDoc::Insert(
957     const SwPaM &rRg,
958     const String& rGrfName,
959     const String& rFltName,
960     const Graphic* pGraphic,
961     const SfxItemSet* pFlyAttrSet,
962     const SfxItemSet* pGrfAttrSet,
963     SwFrmFmt* pFrmFmt )
964 {
965     if ( !pFrmFmt )
966         pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_GRAPHIC );
967     SwGrfNode* pSwGrfNode = GetNodes().MakeGrfNode(
968         SwNodeIndex( GetNodes().GetEndOfAutotext() ),
969         rGrfName, rFltName, pGraphic,
970         pDfltGrfFmtColl );
971     SwFlyFrmFmt* pSwFlyFrmFmt =
972         _InsNoTxtNode( *rRg.GetPoint(), pSwGrfNode, pFlyAttrSet, pGrfAttrSet, pFrmFmt );
973     return pSwFlyFrmFmt;
974 }
975 
976 
Insert(const SwPaM & rRg,const GraphicObject & rGrfObj,const SfxItemSet * pFlyAttrSet,const SfxItemSet * pGrfAttrSet,SwFrmFmt * pFrmFmt)977 SwFlyFrmFmt* SwDoc::Insert(
978     const SwPaM &rRg,
979     const GraphicObject& rGrfObj,
980     const SfxItemSet* pFlyAttrSet,
981     const SfxItemSet* pGrfAttrSet,
982     SwFrmFmt* pFrmFmt )
983 {
984     if ( !pFrmFmt )
985         pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_GRAPHIC );
986     SwGrfNode* pSwGrfNode = GetNodes().MakeGrfNode(
987         SwNodeIndex( GetNodes().GetEndOfAutotext() ),
988         rGrfObj, pDfltGrfFmtColl );
989     SwFlyFrmFmt* pSwFlyFrmFmt = _InsNoTxtNode( *rRg.GetPoint(), pSwGrfNode,
990         pFlyAttrSet, pGrfAttrSet, pFrmFmt );
991     return pSwFlyFrmFmt;
992 }
993 
Insert(const SwPaM & rRg,const svt::EmbeddedObjectRef & xObj,const SfxItemSet * pFlyAttrSet,const SfxItemSet * pGrfAttrSet,SwFrmFmt * pFrmFmt)994 SwFlyFrmFmt* SwDoc::Insert(const SwPaM &rRg, const svt::EmbeddedObjectRef& xObj,
995 						const SfxItemSet* pFlyAttrSet,
996 						const SfxItemSet* pGrfAttrSet,
997 						SwFrmFmt* pFrmFmt )
998 {
999 	if( !pFrmFmt )
1000 	{
1001 		sal_uInt16 nId = RES_POOLFRM_OLE;
1002         SvGlobalName aClassName( xObj->getClassID() );
1003         if (SotExchange::IsMath(aClassName))
1004             nId = RES_POOLFRM_FORMEL;
1005 
1006 		pFrmFmt = GetFrmFmtFromPool( nId );
1007 	}
1008 	return _InsNoTxtNode( *rRg.GetPoint(), GetNodes().MakeOLENode(
1009 							SwNodeIndex( GetNodes().GetEndOfAutotext() ),
1010                             xObj,
1011 							pDfltGrfFmtColl ),
1012 							pFlyAttrSet, pGrfAttrSet,
1013 							pFrmFmt );
1014 }
1015 
InsertOLE(const SwPaM & rRg,const String & rObjName,sal_Int64 nAspect,const SfxItemSet * pFlyAttrSet,const SfxItemSet * pGrfAttrSet,SwFrmFmt * pFrmFmt)1016 SwFlyFrmFmt* SwDoc::InsertOLE(const SwPaM &rRg, const String& rObjName,
1017 						sal_Int64 nAspect,
1018 						const SfxItemSet* pFlyAttrSet,
1019 						const SfxItemSet* pGrfAttrSet,
1020 						SwFrmFmt* pFrmFmt )
1021 {
1022 	if( !pFrmFmt )
1023 		pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_OLE );
1024 
1025 	return _InsNoTxtNode( *rRg.GetPoint(),
1026 							GetNodes().MakeOLENode(
1027 								SwNodeIndex( GetNodes().GetEndOfAutotext() ),
1028 								rObjName,
1029 								nAspect,
1030 								pDfltGrfFmtColl,
1031 								0 ),
1032 							pFlyAttrSet, pGrfAttrSet,
1033 							pFrmFmt );
1034 }
1035 
1036 /*************************************************************************
1037 |*				  SwDoc::GetFldType()
1038 |*	  Description: delivers the field type back which is arranged at the Doc
1039 *************************************************************************/
1040 
GetSysFldType(const sal_uInt16 eWhich) const1041 SwFieldType *SwDoc::GetSysFldType( const sal_uInt16 eWhich ) const
1042 {
1043 	for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i )
1044 		if( eWhich == (*pFldTypes)[i]->Which() )
1045 			return (*pFldTypes)[i];
1046 	return 0;
1047 }
1048 /*************************************************************************
1049  *			   void SetDocStat( const SwDocStat& rStat );
1050  *************************************************************************/
1051 
SetDocStat(const SwDocStat & rStat)1052 void SwDoc::SetDocStat( const SwDocStat& rStat )
1053 {
1054 	*pDocStat = rStat;
1055 }
1056 
GetDocStat() const1057 const SwDocStat& SwDoc::GetDocStat() const
1058 {
1059 	return *pDocStat;
1060 }
1061 
1062 /*************************************************************************/
1063 
1064 
1065 struct _PostItFld : public _SetGetExpFld
1066 {
_PostItFld_PostItFld1067     _PostItFld( const SwNodeIndex& rNdIdx, const SwTxtFld* pFld, const SwIndex* pIdx = 0 )
1068         : _SetGetExpFld( rNdIdx, pFld, pIdx ) {}
1069 
1070     sal_uInt16 GetPageNo( const StringRangeEnumerator &rRangeEnum,
1071             const std::set< sal_Int32 > &rPossiblePages,
1072             sal_uInt16& rVirtPgNo, sal_uInt16& rLineNo );
1073 
GetPostIt_PostItFld1074     SwPostItField* GetPostIt() const
1075     {
1076         return (SwPostItField*) GetTxtFld()->GetFmtFld().GetField();
1077     }
1078 };
1079 
1080 
GetPageNo(const StringRangeEnumerator & rRangeEnum,const std::set<sal_Int32> & rPossiblePages,sal_uInt16 & rVirtPgNo,sal_uInt16 & rLineNo)1081 sal_uInt16 _PostItFld::GetPageNo(
1082     const StringRangeEnumerator &rRangeEnum,
1083     const std::set< sal_Int32 > &rPossiblePages,
1084     /* out */ sal_uInt16& rVirtPgNo, /* out */ sal_uInt16& rLineNo )
1085 {
1086     // Problem:
1087     // When a PostItFld is in a Node that is represented by more than one layout
1088     // instance, then there is the question, whether the PostIt should be printed
1089     // 1 or n-times. Likely only 1 time. Don't seek a random one as page number
1090     // but the first occurrence of the PostIt within the selected area.
1091     rVirtPgNo = 0;
1092     sal_uInt16 nPos = GetCntnt();
1093     SwIterator<SwTxtFrm,SwTxtNode> aIter( GetTxtFld()->GetTxtNode() );
1094     for( SwTxtFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
1095     {
1096         if( pFrm->GetOfst() > nPos ||
1097             (pFrm->HasFollow() && pFrm->GetFollow()->GetOfst() <= nPos) )
1098             continue;
1099         sal_uInt16 nPgNo = pFrm->GetPhyPageNum();
1100         if( rRangeEnum.hasValue( nPgNo, &rPossiblePages ))
1101         {
1102             rLineNo = (sal_uInt16)(pFrm->GetLineCount( nPos ) +
1103                       pFrm->GetAllLines() - pFrm->GetThisLines());
1104             rVirtPgNo = pFrm->GetVirtPageNum();
1105             return nPgNo;
1106         }
1107     }
1108     return 0;
1109 }
1110 
1111 
lcl_GetPostIts(IDocumentFieldsAccess * pIDFA,_SetGetExpFlds * pSrtLst)1112 bool lcl_GetPostIts(
1113     IDocumentFieldsAccess* pIDFA,
1114     _SetGetExpFlds * pSrtLst )
1115 {
1116     bool bHasPostIts = false;
1117 
1118     SwFieldType* pFldType = pIDFA->GetSysFldType( RES_POSTITFLD );
1119     DBG_ASSERT( pFldType, "kein PostItType ? ");
1120 
1121     if( pFldType->GetDepends() )
1122     {
1123         // Modify object found, insert all fields into the array
1124         SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
1125         const SwTxtFld* pTxtFld;
1126         for( SwFmtFld* pFld = aIter.First(); pFld; pFld = aIter.Next() )
1127         {
1128             if( 0 != ( pTxtFld = pFld->GetTxtFld() ) &&
1129                 pTxtFld->GetTxtNode().GetNodes().IsDocNodes() )
1130             {
1131                 bHasPostIts = true;
1132                 if (pSrtLst)
1133                 {
1134                     SwNodeIndex aIdx( pTxtFld->GetTxtNode() );
1135                     _PostItFld* pNew = new _PostItFld( aIdx, pTxtFld );
1136                     pSrtLst->Insert( pNew );
1137                 }
1138                 else
1139                     break;  // we just wanted to check for the existence of postits ...
1140             }
1141         }
1142     }
1143 
1144     return bHasPostIts;
1145 }
1146 
1147 
lcl_FormatPostIt(IDocumentContentOperations * pIDCO,SwPaM & aPam,SwPostItField * pField,bool bNewPage,bool bIsFirstPostIt,sal_uInt16 nPageNo,sal_uInt16 nLineNo)1148 static void lcl_FormatPostIt(
1149     IDocumentContentOperations* pIDCO,
1150     SwPaM& aPam,
1151     SwPostItField* pField,
1152     bool bNewPage, bool bIsFirstPostIt,
1153     sal_uInt16 nPageNo, sal_uInt16 nLineNo )
1154 {
1155     static char __READONLY_DATA sTmp[] = " : ";
1156 
1157     DBG_ASSERT( ViewShell::GetShellRes(), "missing ShellRes" );
1158 
1159     if (bNewPage)
1160     {
1161         pIDCO->InsertPoolItem( aPam, SvxFmtBreakItem( SVX_BREAK_PAGE_AFTER, RES_BREAK ), 0 );
1162         pIDCO->SplitNode( *aPam.GetPoint(), false );
1163     }
1164     else if (!bIsFirstPostIt)
1165     {
1166         // add an empty line between different notes
1167         pIDCO->SplitNode( *aPam.GetPoint(), false );
1168         pIDCO->SplitNode( *aPam.GetPoint(), false );
1169     }
1170 
1171     String aStr( ViewShell::GetShellRes()->aPostItPage );
1172     aStr.AppendAscii(sTmp);
1173 
1174     aStr += XubString::CreateFromInt32( nPageNo );
1175     aStr += ' ';
1176     if( nLineNo )
1177     {
1178         aStr += ViewShell::GetShellRes()->aPostItLine;
1179         aStr.AppendAscii(sTmp);
1180         aStr += XubString::CreateFromInt32( nLineNo );
1181         aStr += ' ';
1182     }
1183     aStr += ViewShell::GetShellRes()->aPostItAuthor;
1184     aStr.AppendAscii(sTmp);
1185     aStr += pField->GetPar1();
1186     aStr += ' ';
1187 	SvtSysLocale aSysLocale;
1188     aStr += /*(LocaleDataWrapper&)*/aSysLocale.GetLocaleData().getDate( pField->GetDate() );
1189     pIDCO->InsertString( aPam, aStr );
1190 
1191     pIDCO->SplitNode( *aPam.GetPoint(), false );
1192     aStr = pField->GetPar2();
1193 #if defined( WNT ) || defined( PM2 )
1194     // Bei Windows und Co alle CR rausschmeissen
1195     aStr.EraseAllChars( '\r' );
1196 #endif
1197     pIDCO->InsertString( aPam, aStr );
1198 }
1199 
1200 
1201 // provide the paper tray to use according to the page style in use,
1202 // but do that only if the respective item is NOT just the default item
lcl_GetPaperBin(const SwPageFrm * pStartFrm)1203 static sal_Int32 lcl_GetPaperBin( const SwPageFrm *pStartFrm )
1204 {
1205     sal_Int32 nRes = -1;
1206 
1207     const SwFrmFmt &rFmt = pStartFrm->GetPageDesc()->GetMaster();
1208     const SfxPoolItem *pItem = NULL;
1209     SfxItemState eState = rFmt.GetItemState( RES_PAPER_BIN, sal_False, &pItem );
1210     const SvxPaperBinItem *pPaperBinItem = dynamic_cast< const SvxPaperBinItem * >(pItem);
1211     if (eState > SFX_ITEM_DEFAULT && pPaperBinItem)
1212         nRes = pPaperBinItem->GetValue();
1213 
1214     return nRes;
1215 }
1216 
1217 
CalculatePagesForPrinting(const SwRootFrm & rLayout,SwRenderData & rData,const SwPrintUIOptions & rOptions,bool bIsPDFExport,sal_Int32 nDocPageCount)1218 void SwDoc::CalculatePagesForPrinting(
1219     const SwRootFrm& rLayout,
1220     /* out */ SwRenderData &rData,
1221     const SwPrintUIOptions &rOptions,
1222     bool bIsPDFExport,
1223     sal_Int32 nDocPageCount )
1224 {
1225     const sal_Int64 nContent = rOptions.getIntValue( "PrintContent", 0 );
1226     const bool bPrintSelection = nContent == 2;
1227 
1228     // properties to take into account when calculating the set of pages
1229     // (PDF export UI does not allow for selecting left or right pages only)
1230     bool bPrintLeftPages    = bIsPDFExport ? true : rOptions.IsPrintLeftPages();
1231     bool bPrintRightPages   = bIsPDFExport ? true : rOptions.IsPrintRightPages();
1232     // #i103700# printing selections should not allow for automatic inserting empty pages
1233     bool bPrintEmptyPages   = bPrintSelection ? false : rOptions.IsPrintEmptyPages( bIsPDFExport );
1234 
1235     Range aPages( 1, nDocPageCount );
1236 
1237     MultiSelection aMulti( aPages );
1238     aMulti.SetTotalRange( Range( 0, RANGE_MAX ) );
1239     aMulti.Select( aPages );
1240 
1241     const SwPageFrm *pStPage  = dynamic_cast<const SwPageFrm*>( rLayout.Lower() );
1242     const SwFrm     *pEndPage = pStPage;
1243 
1244     sal_uInt16 nFirstPageNo = 0;
1245     sal_uInt16 nLastPageNo  = 0;
1246     sal_uInt16 nPageNo      = 1;
1247 
1248     for( sal_uInt16 i = 1; i <= (sal_uInt16)aPages.Max(); ++i )
1249     {
1250         if( i < (sal_uInt16)aPages.Min() )
1251         {
1252             if( !pStPage->GetNext() )
1253                 break;
1254             pStPage = (SwPageFrm*)pStPage->GetNext();
1255             pEndPage= pStPage;
1256         }
1257         else if( i == (sal_uInt16)aPages.Min() )
1258         {
1259             nFirstPageNo = i;
1260             nLastPageNo = nFirstPageNo;
1261             if( !pStPage->GetNext() || (i == (sal_uInt16)aPages.Max()) )
1262                 break;
1263             pEndPage = pStPage->GetNext();
1264         }
1265         else if( i > (sal_uInt16)aPages.Min() )
1266         {
1267             nLastPageNo = i;
1268             if( !pEndPage->GetNext() || (i == (sal_uInt16)aPages.Max()) )
1269                 break;
1270             pEndPage = pEndPage->GetNext();
1271         }
1272     }
1273 
1274     DBG_ASSERT( nFirstPageNo, "first page not found!  Should not happen!" );
1275     if (nFirstPageNo)
1276     {
1277 // Start of HACK:
1278 // Here an acceptable possibility has to be created by the MultiSelection,
1279 // to deselect all pages starting from page x.
1280 // E.g., with SetTotalRange ....
1281 
1282 // aMulti.Select( Range( nLastPageNo+1, SELECTION_MAX ), sal_False );
1283         MultiSelection aTmpMulti( Range( 1, nLastPageNo ) );
1284         long nTmpIdx = aMulti.FirstSelected();
1285         static long nEndOfSelection = SFX_ENDOFSELECTION;
1286         while ( nEndOfSelection != nTmpIdx && nTmpIdx <= long(nLastPageNo) )
1287         {
1288             aTmpMulti.Select( nTmpIdx );
1289             nTmpIdx = aMulti.NextSelected();
1290         }
1291         aMulti = aTmpMulti;
1292 // End of HACK
1293 
1294         nPageNo = nFirstPageNo;
1295 
1296         std::map< sal_Int32, sal_Int32 > &rPrinterPaperTrays = rData.GetPrinterPaperTrays();
1297         std::set< sal_Int32 > &rValidPages = rData.GetValidPagesSet();
1298         std::map< sal_Int32, const SwPageFrm * > &rValidStartFrms = rData.GetValidStartFrames();
1299         rValidPages.clear();
1300         rValidStartFrms.clear();
1301         while ( pStPage )
1302         {
1303             const sal_Bool bRightPg = pStPage->OnRightPage();
1304             if ( aMulti.IsSelected( nPageNo ) &&
1305                 ( (bRightPg && bPrintRightPages) ||
1306                     (!bRightPg && bPrintLeftPages) ) )
1307             {
1308                 // --> FME 2005-12-12 #b6354161# Feature - Print empty pages
1309                 if ( bPrintEmptyPages || pStPage->Frm().Height() )
1310                 // <--
1311                 {
1312                     rValidPages.insert( nPageNo );
1313                     rValidStartFrms[ nPageNo ] = pStPage;
1314 
1315                     rPrinterPaperTrays[ nPageNo ] = lcl_GetPaperBin( pStPage );
1316                 }
1317             }
1318 
1319             if ( pStPage == pEndPage )
1320             {
1321                 pStPage = 0;
1322             }
1323             else
1324             {   ++nPageNo;
1325                 pStPage = (SwPageFrm*)pStPage->GetNext();
1326             }
1327         }
1328     }
1329 
1330     // now that we have identified the valid pages for printing according
1331     // to the print settings we need to get the PageRange to use and
1332     // use both results to get the actual pages to be printed
1333     // (post-it settings need to be taken into account later on!)
1334 
1335     // get PageRange value to use
1336     OUString aPageRange;
1337     // --> PL, OD #i116085# - adjusting fix for i113919
1338 //    if (bIsPDFExport)
1339 //    {
1340 //        aPageRange = rOptions.getStringValue( "PageRange", OUString() );
1341 //    }
1342 //    else
1343     if ( !bIsPDFExport )
1344     // <--
1345     {
1346         // PageContent :
1347         // 0 -> print all pages (default if aPageRange is empty)
1348         // 1 -> print range according to PageRange
1349         // 2 -> print selection
1350         if (1 == nContent)
1351             aPageRange = rOptions.getStringValue( "PageRange", OUString() );
1352         if (2 == nContent)
1353         {
1354             // note that printing selections is actually implemented by copying
1355             // the selection to a new temporary document and printing all of that one.
1356             // Thus for Writer "PrintContent" must never be 2.
1357             // See SwXTextDocument::GetRenderDoc for evaluating if a selection is to be
1358             // printed and for creating the temporary document.
1359         }
1360 
1361         // please note
1362     }
1363     if (aPageRange.getLength() == 0)    // empty string -> print all
1364     {
1365         // set page range to print to 'all pages'
1366         aPageRange = OUString::valueOf( (sal_Int32)1 );
1367         aPageRange += OUString::valueOf( (sal_Unicode)'-');
1368         aPageRange += OUString::valueOf( nDocPageCount );
1369     }
1370     rData.SetPageRange( aPageRange );
1371 
1372     // get vector of pages to print according to PageRange and valid pages set from above
1373     // (result may be an empty vector, for example if the range string is not correct)
1374     StringRangeEnumerator::getRangesFromString(
1375             aPageRange, rData.GetPagesToPrint(),
1376             1, nDocPageCount, 0, &rData.GetValidPagesSet() );
1377 }
1378 
1379 
UpdatePagesForPrintingWithPostItData(SwRenderData & rData,const SwPrintUIOptions & rOptions,bool,sal_Int32 nDocPageCount)1380 void SwDoc::UpdatePagesForPrintingWithPostItData(
1381     /* out */ SwRenderData &rData,
1382     const SwPrintUIOptions &rOptions,
1383     bool /*bIsPDFExport*/,
1384     sal_Int32 nDocPageCount )
1385 {
1386 
1387     sal_Int16 nPostItMode = (sal_Int16) rOptions.getIntValue( "PrintAnnotationMode", 0 );
1388     DBG_ASSERT(nPostItMode == POSTITS_NONE || rData.HasPostItData(),
1389             "print post-its without post-it data?" );
1390     const sal_uInt16 nPostItCount = rData.HasPostItData() ? rData.m_pPostItFields->Count() : 0;
1391     if (nPostItMode != POSTITS_NONE && nPostItCount > 0)
1392     {
1393         SET_CURR_SHELL( rData.m_pPostItShell );
1394 
1395         // clear document and move to end of it
1396         SwPaM aPam( rData.m_pPostItDoc->GetNodes().GetEndOfContent() );
1397         aPam.Move( fnMoveBackward, fnGoDoc );
1398         aPam.SetMark();
1399         aPam.Move( fnMoveForward, fnGoDoc );
1400         rData.m_pPostItDoc->DeleteRange( aPam );
1401 
1402         const StringRangeEnumerator aRangeEnum( rData.GetPageRange(), 1, nDocPageCount, 0 );
1403 
1404         // For mode POSTITS_ENDPAGE:
1405         // maps a physical page number to the page number in post-it document that holds
1406         // the first post-it for that physical page . Needed to relate the correct start frames
1407         // from the post-it doc to the physical page of the document
1408         std::map< sal_Int32, sal_Int32 > aPostItLastStartPageNum;
1409 
1410         // add all post-its on valid pages within the page range to the
1411         // temporary post-it document.
1412         // Since the array of post-it fields is sorted by page and line number we will
1413         // already get them in the correct order
1414         sal_uInt16 nVirtPg = 0, nLineNo = 0, nLastPageNum = 0, nPhyPageNum = 0;
1415         bool bIsFirstPostIt = true;
1416         for (sal_uInt16 i = 0; i < nPostItCount; ++i)
1417         {
1418             _PostItFld& rPostIt = (_PostItFld&)*(*rData.m_pPostItFields)[ i ];
1419             nLastPageNum = nPhyPageNum;
1420             nPhyPageNum = rPostIt.GetPageNo(
1421                     aRangeEnum, rData.GetValidPagesSet(), nVirtPg, nLineNo );
1422             if (nPhyPageNum)
1423             {
1424                 // need to insert a page break?
1425                 // In POSTITS_ENDPAGE mode for each document page the following
1426                 // post-it page needs to start on a new page
1427                 const bool bNewPage = nPostItMode == POSTITS_ENDPAGE &&
1428                         !bIsFirstPostIt && nPhyPageNum != nLastPageNum;
1429 
1430                 lcl_FormatPostIt( rData.m_pPostItShell->GetDoc(), aPam,
1431                         rPostIt.GetPostIt(), bNewPage, bIsFirstPostIt, nVirtPg, nLineNo );
1432                 bIsFirstPostIt = false;
1433 
1434                 if (nPostItMode == POSTITS_ENDPAGE)
1435                 {
1436                     // get the correct number of current pages for the post-it document
1437                     rData.m_pPostItShell->CalcLayout();
1438                     const sal_Int32 nPages = rData.m_pPostItShell->GetPageCount();
1439                     aPostItLastStartPageNum[ nPhyPageNum ] = nPages;
1440                 }
1441             }
1442         }
1443 
1444         // format post-it doc to get correct number of pages
1445         rData.m_pPostItShell->CalcLayout();
1446         const sal_Int32 nPostItDocPageCount = rData.m_pPostItShell->GetPageCount();
1447 
1448         if (nPostItMode == POSTITS_ONLY || nPostItMode == POSTITS_ENDDOC)
1449         {
1450             // now add those post-it pages to the vector of pages to print
1451             // or replace them if only post-its should be printed
1452 
1453             rData.GetPostItStartFrames().clear();
1454             if (nPostItMode == POSTITS_ENDDOC)
1455             {
1456                 // set all values up to number of pages to print currently known to NULL,
1457                 // meaning none of the pages currently in the vector is from the
1458                 // post-it document, they are the documents pages.
1459                 rData.GetPostItStartFrames().resize( rData.GetPagesToPrint().size() );
1460             }
1461             else if (nPostItMode == POSTITS_ONLY)
1462             {
1463                 // no document page to be printed
1464                 rData.GetPagesToPrint().clear();
1465             }
1466 
1467             // now we just need to add the post-it pages to be printed to the end
1468             // of the vector of pages to print and keep the GetValidStartFrames
1469             // data conform with it
1470             sal_Int32 nPageNum = 0;
1471             const SwPageFrm * pPageFrm = (SwPageFrm*)rData.m_pPostItShell->GetLayout()->Lower();
1472             while( pPageFrm && nPageNum < nPostItDocPageCount )
1473             {
1474                 DBG_ASSERT( pPageFrm, "Empty page frame. How are we going to print this?" );
1475                 ++nPageNum;
1476                 rData.GetPagesToPrint().push_back( 0 ); // a page number of 0 indicates this page is from the post-it doc
1477                 DBG_ASSERT( pPageFrm, "pPageFrm is NULL!" );
1478                 rData.GetPostItStartFrames().push_back( pPageFrm );
1479                 pPageFrm = (SwPageFrm*)pPageFrm->GetNext();
1480             }
1481             DBG_ASSERT( nPageNum == nPostItDocPageCount, "unexpected number of pages" );
1482         }
1483         else if (nPostItMode == POSTITS_ENDPAGE)
1484         {
1485             // the next step is to find all the start frames from the post-it
1486             // document that should be printed for a given physical page of the document
1487             std::map< sal_Int32, std::vector< const SwPageFrm * > > aPhysPageToPostItFrames;
1488 
1489             // ... thus, first collect all post-it doc start frames in a vector
1490             sal_Int32 nPostItPageNum = 0;
1491             std::vector< const SwPageFrm * > aAllPostItStartFrames;
1492             const SwPageFrm * pPageFrm = (SwPageFrm*)rData.m_pPostItShell->GetLayout()->Lower();
1493             while( pPageFrm && sal_Int32(aAllPostItStartFrames.size()) < nPostItDocPageCount )
1494             {
1495                 DBG_ASSERT( pPageFrm, "Empty page frame. How are we going to print this?" );
1496                 ++nPostItPageNum;
1497                 aAllPostItStartFrames.push_back( pPageFrm );
1498                 pPageFrm = (SwPageFrm*)pPageFrm->GetNext();
1499             }
1500             DBG_ASSERT( sal_Int32(aAllPostItStartFrames.size()) == nPostItDocPageCount,
1501                     "unexpected number of frames; does not match number of pages" );
1502 
1503             // get a map that holds all post-it frames to be printed for a
1504             // given physical page from the document
1505             sal_Int32 nLastStartPageNum = 0;
1506             std::map< sal_Int32, sal_Int32 >::const_iterator aIt;
1507             for (aIt = aPostItLastStartPageNum.begin(); aIt != aPostItLastStartPageNum.end(); ++aIt)
1508             {
1509                 const sal_Int32 nFrames = aIt->second - nLastStartPageNum;
1510                 const sal_Int32 nFirstStartPageNum = aIt == aPostItLastStartPageNum.begin() ?
1511                         1 : aIt->second - nFrames + 1;
1512                 DBG_ASSERT( 1 <= nFirstStartPageNum && nFirstStartPageNum <= nPostItDocPageCount,
1513                         "page number for first frame out of range" );
1514                 std::vector<  const SwPageFrm * > aStartFrames;
1515                 for (sal_Int32 i = 0; i < nFrames; ++i)
1516                 {
1517                     const sal_Int32 nIdx = nFirstStartPageNum - 1 + i;   // -1 because lowest page num is 1
1518                     DBG_ASSERT( 0 <= nIdx && nIdx < sal_Int32(aAllPostItStartFrames.size()),
1519                             "index out of range" );
1520                     aStartFrames.push_back( aAllPostItStartFrames[ nIdx ] );
1521                 }
1522                 aPhysPageToPostItFrames[ aIt->first /* phys page num */ ] = aStartFrames;
1523                 nLastStartPageNum = aIt->second;
1524             }
1525 
1526 
1527             // ok, now that aPhysPageToPostItFrames can give the start frames for all
1528             // post-it pages to be printed we need to merge those at the correct
1529             // position into the GetPagesToPrint vector and build and maintain the
1530             // GetValidStartFrames vector as well.
1531             // Since inserting a larger number of entries in the middle of a vector
1532             // isn't that efficient we will create new vectors by copying the required data
1533             std::vector< sal_Int32 >            aTmpPagesToPrint;
1534             std::vector< const SwPageFrm * >    aTmpPostItStartFrames;
1535             const size_t nNum = rData.GetPagesToPrint().size();
1536             for (size_t i = 0 ;  i < nNum;  ++i)
1537             {
1538                 // add the physical page to print from the document
1539                 const sal_Int32 nPhysPage = rData.GetPagesToPrint()[i];
1540                 aTmpPagesToPrint.push_back( nPhysPage );
1541                 aTmpPostItStartFrames.push_back( NULL );
1542 
1543                 // add the post-it document pages to print, i.e. those
1544                 // post-it pages that have the data for the above physical page
1545                 const std::vector< const SwPageFrm * > &rPostItFrames = aPhysPageToPostItFrames[ nPhysPage ];
1546                 const size_t nPostItFrames = rPostItFrames.size();
1547                 for (size_t k = 0;  k < nPostItFrames;  ++k)
1548                 {
1549                     aTmpPagesToPrint.push_back( 0 );
1550                     aTmpPostItStartFrames.push_back( rPostItFrames[k] );
1551                 }
1552             }
1553 
1554             // finally we need to assign those vectors to the resulting ones.
1555             // swapping the data should be more efficient than assigning since
1556             // we won't need the temporary vectors anymore
1557             rData.GetPagesToPrint().swap( aTmpPagesToPrint );
1558             rData.GetPostItStartFrames().swap( aTmpPostItStartFrames );
1559         }
1560     }
1561 }
1562 
1563 
CalculatePagePairsForProspectPrinting(const SwRootFrm & rLayout,SwRenderData & rData,const SwPrintUIOptions & rOptions,sal_Int32 nDocPageCount)1564 void SwDoc::CalculatePagePairsForProspectPrinting(
1565     const SwRootFrm& rLayout,
1566     /* out */ SwRenderData &rData,
1567     const SwPrintUIOptions &rOptions,
1568     sal_Int32 nDocPageCount )
1569 {
1570     std::map< sal_Int32, sal_Int32 > &rPrinterPaperTrays = rData.GetPrinterPaperTrays();
1571     std::set< sal_Int32 > &rValidPagesSet = rData.GetValidPagesSet();
1572     std::map< sal_Int32, const SwPageFrm * > &rValidStartFrms = rData.GetValidStartFrames();
1573     std::vector< std::pair< sal_Int32, sal_Int32 > > &rPagePairs = rData.GetPagePairsForProspectPrinting();
1574 
1575     rPagePairs.clear();
1576     rValidPagesSet.clear();
1577     rValidStartFrms.clear();
1578 
1579     rtl::OUString aPageRange = rOptions.getStringValue( "PageRange", rtl::OUString() );
1580     // PageContent :
1581     // 0 -> print all pages (default if aPageRange is empty)
1582     // 1 -> print range according to PageRange
1583     // 2 -> print selection
1584     const sal_Int64 nContent = rOptions.getIntValue( "PrintContent", 0 );
1585     if (0 == nContent)
1586     {
1587         // set page range to print to 'all pages'
1588         aPageRange = OUString::valueOf( (sal_Int32)1 );
1589         aPageRange += OUString::valueOf( (sal_Unicode)'-');
1590         aPageRange += OUString::valueOf( nDocPageCount );
1591     }
1592     StringRangeEnumerator aRange( aPageRange, 1, nDocPageCount, 0 );
1593 
1594     if ( aRange.size() <= 0)
1595         return;
1596 
1597     const SwPageFrm *pStPage = dynamic_cast<const SwPageFrm*>( rLayout.Lower() );
1598     sal_Int32 i = 0;
1599     for ( i = 1; pStPage && i < nDocPageCount; ++i )
1600         pStPage = (SwPageFrm*)pStPage->GetNext();
1601     if ( !pStPage )          // that's it then
1602         return;
1603 
1604     // currently for prospect printing all pages are valid to be printed
1605     // thus we add them all to the respective map and set for later use
1606     sal_Int32 nPageNum = 0;
1607     const SwPageFrm *pPageFrm = dynamic_cast<const SwPageFrm*>( rLayout.Lower() );
1608     while( pPageFrm && nPageNum < nDocPageCount )
1609     {
1610         DBG_ASSERT( pPageFrm, "Empty page frame. How are we going to print this?" );
1611         ++nPageNum;
1612         rValidPagesSet.insert( nPageNum );
1613         rValidStartFrms[ nPageNum ] = pPageFrm;
1614         pPageFrm = (SwPageFrm*)pPageFrm->GetNext();
1615 
1616         rPrinterPaperTrays[ nPageNum ] = lcl_GetPaperBin( pStPage );
1617     }
1618     DBG_ASSERT( nPageNum == nDocPageCount, "unexpected number of pages" );
1619 
1620     // properties to take into account when calculating the set of pages
1621     // Note: here bPrintLeftPages and bPrintRightPages refer to the (virtual) resulting pages
1622     //      of the prospect!
1623     bool bPrintLeftPages     = rOptions.IsPrintLeftPages();
1624     bool bPrintRightPages    = rOptions.IsPrintRightPages();
1625     bool bPrintProspectRTL = rOptions.getIntValue( "PrintProspectRTL", 0 ) ? true : false;
1626 
1627     // get pages for prospect printing according to the 'PageRange'
1628     // (duplicates and any order allowed!)
1629     std::vector< sal_Int32 > aPagesToPrint;
1630     StringRangeEnumerator::getRangesFromString(
1631             aPageRange, aPagesToPrint, 1, nDocPageCount, 0 );
1632 
1633     // now fill the vector for calculating the page pairs with the start frames
1634     // from the above obtained vector
1635     std::vector< const SwPageFrm * > aVec;
1636     for ( i = 0; i < sal_Int32(aPagesToPrint.size()); ++i)
1637     {
1638         const sal_Int32 nPage = aPagesToPrint[i];
1639         const SwPageFrm *pFrm = rValidStartFrms[ nPage ];
1640         aVec.push_back( pFrm );
1641     }
1642 
1643     // just one page is special ...
1644     if ( 1 == aVec.size() )
1645         aVec.insert( aVec.begin() + 1, 0 ); // insert a second empty page
1646     else
1647     {
1648         // now extend the number of pages to fit a multiple of 4
1649         // (4 'normal' pages are needed for a single prospect paper
1650         //  with back and front)
1651         while( aVec.size() & 3 )
1652             aVec.push_back( 0 );
1653     }
1654 
1655     // now make sure that all pages are in the correct order
1656     sal_uInt16 nSPg = 0;
1657     sal_uInt32 nEPg = aVec.size();
1658     sal_uInt16 nStep = 1;
1659     if ( 0 == (nEPg & 1 ))      // there is no odd!
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 
UpdateDocStat(SwDocStat & rStat)1715 void SwDoc::UpdateDocStat( SwDocStat& rStat )
1716 {
1717 	if( rStat.bModified )
1718 	{
1719 		rStat.Reset();
1720 		rStat.nPara = 0;        // default is 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 		// if necessary update statistical fields
1795 		SwFieldType *pType = GetSysFldType(RES_DOCSTATFLD);
1796 		pType->UpdateFlds();
1797 	}
1798 }
1799 
1800 
1801 // Document - Info
1802 
DocInfoChgd()1803 void SwDoc::DocInfoChgd( )
1804 {
1805 	GetSysFldType( RES_DOCINFOFLD )->UpdateFlds();
1806 	GetSysFldType( RES_TEMPLNAMEFLD )->UpdateFlds();
1807 	SetModified();
1808 }
1809 
1810 	// return the reference that is set in the Doc, together with the name
GetRefMark(const String & rName) const1811 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 	// return the RefMark by Index - for Uno
GetRefMark(sal_uInt16 nIndex) const1830 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 	// return the names of all references that are set in the Doc
1854 	// JP 24.06.96: If the ArrayPointer is 0 then return only when a RefMark is set in the Doc
1855 	// OS 25.06.96: from now on always return the number of the references
GetRefMarks(SvStringsDtor * pNames) const1856 sal_uInt16 SwDoc::GetRefMarks( SvStringsDtor* pNames ) const
1857 {
1858 	const SfxPoolItem* pItem;
1859 	const SwTxtRefMark* pTxtRef;
1860 
1861     const sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK );
1862     sal_uInt16 nCount = 0;
1863     for( sal_uInt32 n = 0; n < nMaxItems; ++n )
1864         if( 0 != (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n )) &&
1865             0 != (pTxtRef = ((SwFmtRefMark*)pItem)->GetTxtRefMark()) &&
1866             &pTxtRef->GetTxtNode().GetNodes() == &GetNodes() )
1867         {
1868             if( pNames )
1869             {
1870                 String* pTmp = new String( ((SwFmtRefMark*)pItem)->GetRefName() );
1871                 pNames->Insert( pTmp, nCount );
1872             }
1873             ++nCount;
1874         }
1875 
1876 	return nCount;
1877 }
1878 
IsLoaded() const1879 bool SwDoc::IsLoaded() const
1880 {
1881 	return mbLoaded;
1882 }
1883 
IsUpdateExpFld() const1884 bool SwDoc::IsUpdateExpFld() const
1885 {
1886 	return mbUpdateExpFld;
1887 }
1888 
IsNewDoc() const1889 bool SwDoc::IsNewDoc() const
1890 {
1891 	return mbNewDoc;
1892 }
1893 
IsPageNums() const1894 bool SwDoc::IsPageNums() const
1895 {
1896 	return mbPageNums;
1897 }
1898 
SetPageNums(bool b)1899 void SwDoc::SetPageNums(bool b)
1900 {
1901 	mbPageNums = b;
1902 }
1903 
SetNewDoc(bool b)1904 void SwDoc::SetNewDoc(bool b)
1905 {
1906 	mbNewDoc = b;
1907 }
1908 
SetUpdateExpFldStat(bool b)1909 void SwDoc::SetUpdateExpFldStat(bool b)
1910 {
1911 	mbUpdateExpFld = b;
1912 }
1913 
SetLoaded(bool b)1914 void SwDoc::SetLoaded(bool b)
1915 {
1916 	mbLoaded = b;
1917 }
1918 
IsModified() const1919 bool SwDoc::IsModified() const
1920 {
1921 	return mbModified;
1922 }
1923 
SetModified()1924 void SwDoc::SetModified()
1925 {
1926 	// --> OD 2005-08-29 #125370#
1927 	SwLayouter::ClearMovedFwdFrms( *this );
1928 	SwLayouter::ClearObjsTmpConsiderWrapInfluence( *this );
1929 	SwLayouter::ClearFrmsNotToWrap( *this );
1930 	// <--
1931 	// --> OD 2006-05-10 #i65250#
1932 	SwLayouter::ClearMoveBwdLayoutInfo( *this );
1933 	// <--
1934 	// return the status to the link, how the flags were and will be
1935 	// 	Bit 0:	-> old status
1936 	//	Bit 1: 	-> new status
1937 	long nCall = mbModified ? 3 : 2;
1938 	mbModified = sal_True;
1939 	pDocStat->bModified = sal_True;
1940 	if( aOle2Link.IsSet() )
1941 	{
1942 		mbInCallModified = sal_True;
1943 		aOle2Link.Call( (void*)nCall );
1944 		mbInCallModified = sal_False;
1945 	}
1946 
1947 	if( pACEWord && !pACEWord->IsDeleted() )
1948 		delete pACEWord, pACEWord = 0;
1949 }
1950 
ResetModified()1951 void SwDoc::ResetModified()
1952 {
1953 	// return the status to the link, how the flags were and will be
1954 	// 	Bit 0:	-> old status
1955 	//	Bit 1: 	-> new status
1956 	long nCall = mbModified ? 1 : 0;
1957 	mbModified = sal_False;
1958 	// If there is already a document statistic, we assume that
1959 	// it is correct. In this case we reset the modified flag.
1960 	if ( 0 != pDocStat->nChar )
1961 		pDocStat->bModified = sal_False;
1962 	GetIDocumentUndoRedo().SetUndoNoModifiedPosition();
1963 	if( nCall && aOle2Link.IsSet() )
1964 	{
1965 		mbInCallModified = sal_True;
1966 		aOle2Link.Call( (void*)nCall );
1967 		mbInCallModified = sal_False;
1968 	}
1969 }
1970 
1971 
ReRead(SwPaM & rPam,const String & rGrfName,const String & rFltName,const Graphic * pGraphic,const GraphicObject * pGrafObj)1972 void SwDoc::ReRead( SwPaM& rPam, const String& rGrfName,
1973 					const String& rFltName, const Graphic* pGraphic,
1974 					const GraphicObject* pGrafObj )
1975 {
1976 	SwGrfNode *pGrfNd;
1977 	if( ( !rPam.HasMark()
1978 		 || rPam.GetPoint()->nNode.GetIndex() == rPam.GetMark()->nNode.GetIndex() )
1979 		 && 0 != ( pGrfNd = rPam.GetPoint()->nNode.GetNode().GetGrfNode() ) )
1980 	{
1981 		if (GetIDocumentUndoRedo().DoesUndo())
1982 		{
1983 			GetIDocumentUndoRedo().AppendUndo(new SwUndoReRead(rPam, *pGrfNd));
1984 		}
1985 
1986 		// Because it's not known if the graphic can be mirrored,
1987 		// always set back the MirrorAttribute
1988 		if( RES_MIRROR_GRAPH_DONT != pGrfNd->GetSwAttrSet().
1989 												GetMirrorGrf().GetValue() )
1990 			pGrfNd->SetAttr( SwMirrorGrf() );
1991 
1992 		pGrfNd->ReRead( rGrfName, rFltName, pGraphic, pGrafObj, sal_True );
1993 		SetModified();
1994 	}
1995 }
1996 
lcl_SpellAndGrammarAgain(const SwNodePtr & rpNd,void * pArgs)1997 sal_Bool lcl_SpellAndGrammarAgain( const SwNodePtr& rpNd, void* pArgs )
1998 {
1999 	SwTxtNode *pTxtNode = (SwTxtNode*)rpNd->GetTxtNode();
2000 	sal_Bool bOnlyWrong = *(sal_Bool*)pArgs;
2001 	if( pTxtNode )
2002 	{
2003 		if( bOnlyWrong )
2004 		{
2005 			if( pTxtNode->GetWrong() &&
2006 				pTxtNode->GetWrong()->InvalidateWrong() )
2007                 pTxtNode->SetWrongDirty( true );
2008             if( pTxtNode->GetGrammarCheck() &&
2009                 pTxtNode->GetGrammarCheck()->InvalidateWrong() )
2010                 pTxtNode->SetGrammarCheckDirty( true );
2011 		}
2012 		else
2013 		{
2014             pTxtNode->SetWrongDirty( true );
2015 			if( pTxtNode->GetWrong() )
2016 				pTxtNode->GetWrong()->SetInvalid( 0, STRING_LEN );
2017             pTxtNode->SetGrammarCheckDirty( true );
2018             if( pTxtNode->GetGrammarCheck() )
2019                 pTxtNode->GetGrammarCheck()->SetInvalid( 0, STRING_LEN );
2020 		}
2021 	}
2022 	return sal_True;
2023 }
2024 
lcl_CheckSmartTagsAgain(const SwNodePtr & rpNd,void *)2025 sal_Bool lcl_CheckSmartTagsAgain( const SwNodePtr& rpNd, void* )
2026 {
2027 	SwTxtNode *pTxtNode = (SwTxtNode*)rpNd->GetTxtNode();
2028 //	sal_Bool bOnlyWrong = *(sal_Bool*)pArgs;
2029 	if( pTxtNode )
2030 	{
2031         pTxtNode->SetSmartTagDirty( true );
2032         if( pTxtNode->GetSmartTags() )
2033         {
2034 //            if ( bOnlyWrong ) // only some smart tag types have been enabled or disabled
2035 //				pTxtNode->GetSmartTags()->SetInvalid( 0, STRING_LEN );
2036 //            else // smart tags all have been enabled or disabled
2037 				pTxtNode->SetSmartTags( NULL );
2038         }
2039 	}
2040 	return sal_True;
2041 }
2042 
2043 
2044 /*************************************************************************
2045  * 		SwDoc::SpellItAgainSam( sal_Bool bInvalid, sal_Bool bOnlyWrong )
2046  *
2047  * Is activating again the spelling in the Idle handler.
2048  * When bInvalid will be hand over as sal_True, then additionally the WrongLists
2049  * on all Nodes will be invalidated and on all pages the SpellInvalid flag
2050  * will be set.
2051  * With bOnlyWrong you can control, whether only the areas with wrong words
2052  * or the complete areas have to be checked again.
2053  ************************************************************************/
2054 
SpellItAgainSam(sal_Bool bInvalid,sal_Bool bOnlyWrong,sal_Bool bSmartTags)2055 void SwDoc::SpellItAgainSam( sal_Bool bInvalid, sal_Bool bOnlyWrong, sal_Bool bSmartTags )
2056 {
2057 	std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080307
2058 	ASSERT( GetCurrentLayout(), "SpellAgain: Where's my RootFrm?" );
2059 	if( bInvalid )
2060 	{
2061 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::AllInvalidateSmartTagsOrSpelling),bSmartTags));//swmod 080305
2062 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::SetNeedGrammarCheck), true) );
2063 		if ( bSmartTags )
2064 			GetNodes().ForEach( lcl_CheckSmartTagsAgain, &bOnlyWrong );
2065 		GetNodes().ForEach( lcl_SpellAndGrammarAgain, &bOnlyWrong );
2066 	}
2067 
2068 	std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::SetIdleFlags));//swmod 080307
2069 }
2070 
InvalidateAutoCompleteFlag()2071 void SwDoc::InvalidateAutoCompleteFlag()
2072 {
2073 	SwRootFrm* pTmpRoot = GetCurrentLayout();
2074 	if( pTmpRoot )
2075 	{
2076 		std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
2077 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllInvalidateAutoCompleteWords));//swmod 080305
2078 		for( sal_uLong nNd = 1, nCnt = GetNodes().Count(); nNd < nCnt; ++nNd )
2079         {
2080             SwTxtNode* pTxtNode = GetNodes()[ nNd ]->GetTxtNode();
2081             if ( pTxtNode ) pTxtNode->SetAutoCompleteWordDirty( true );
2082         }
2083 
2084 		std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::SetIdleFlags));//swmod 080228
2085 	}	//swmod 080219
2086 }
2087 
FindINetAttr(const String & rName) const2088 const SwFmtINetFmt* SwDoc::FindINetAttr( const String& rName ) const
2089 {
2090 	const SwFmtINetFmt* pItem;
2091 	const SwTxtINetFmt* pTxtAttr;
2092 	const SwTxtNode* pTxtNd;
2093 	sal_uInt32 n, nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
2094 	for( n = 0; n < nMaxItems; ++n )
2095 		if( 0 != (pItem = (SwFmtINetFmt*)GetAttrPool().GetItem2(
2096 			RES_TXTATR_INETFMT, n ) ) &&
2097 			pItem->GetName().Equals( rName ) &&
2098 			0 != ( pTxtAttr = pItem->GetTxtINetFmt()) &&
2099 			0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
2100 			&pTxtNd->GetNodes() == &GetNodes() )
2101 		{
2102 			return pItem;
2103 		}
2104 
2105 	return 0;
2106 }
2107 
Summary(SwDoc * pExtDoc,sal_uInt8 nLevel,sal_uInt8 nPara,sal_Bool bImpress)2108 void SwDoc::Summary( SwDoc* pExtDoc, sal_uInt8 nLevel, sal_uInt8 nPara, sal_Bool bImpress )
2109 {
2110 	const SwOutlineNodes& rOutNds = GetNodes().GetOutLineNds();
2111 	if( pExtDoc && rOutNds.Count() )
2112 	{
2113 		sal_uInt16 i;
2114 		::StartProgress( STR_STATSTR_SUMMARY, 0, rOutNds.Count(), GetDocShell() );
2115 		SwNodeIndex aEndOfDoc( pExtDoc->GetNodes().GetEndOfContent(), -1 );
2116 		for( i = 0; i < rOutNds.Count(); ++i )
2117 		{
2118 			::SetProgressState( i, GetDocShell() );
2119             const sal_uLong nIndex = rOutNds[ i ]->GetIndex();
2120 			//sal_uInt8 nLvl = ((SwTxtNode*)GetNodes()[ nIndex ])->GetTxtColl()//#outline level,zhaojianwei
2121 						// ->GetOutlineLevel();
2122             const int nLvl = ((SwTxtNode*)GetNodes()[ nIndex ])->GetAttrOutlineLevel()-1;//<-end,zhaojianwei
2123 			if( nLvl > nLevel )
2124 				continue;
2125 			sal_uInt16 nEndOfs = 1;
2126 			sal_uInt8 nWish = nPara;
2127 			sal_uLong nNextOutNd = i + 1 < rOutNds.Count() ?
2128 				rOutNds[ i + 1 ]->GetIndex() : GetNodes().Count();
2129 			sal_Bool bKeep = sal_False;
2130 			while( ( nWish || bKeep ) && nIndex + nEndOfs < nNextOutNd &&
2131 				   GetNodes()[ nIndex + nEndOfs ]->IsTxtNode() )
2132 			{
2133 				SwTxtNode* pTxtNode = (SwTxtNode*)GetNodes()[ nIndex+nEndOfs ];
2134 				if( pTxtNode->GetTxt().Len() && nWish )
2135 					--nWish;
2136 				bKeep = pTxtNode->GetSwAttrSet().GetKeep().GetValue();
2137 				++nEndOfs;
2138 			}
2139 
2140 			SwNodeRange aRange( *rOutNds[ i ], 0, *rOutNds[ i ], nEndOfs );
2141 			GetNodes()._Copy( aRange, aEndOfDoc );
2142 		}
2143 		const SwTxtFmtColls *pColl = pExtDoc->GetTxtFmtColls();
2144 		for( i = 0; i < pColl->Count(); ++i )
2145             (*pColl)[ i ]->ResetFmtAttr( RES_PAGEDESC, RES_BREAK );
2146 		SwNodeIndex aIndx( pExtDoc->GetNodes().GetEndOfExtras() );
2147 		++aEndOfDoc;
2148 		while( aIndx < aEndOfDoc )
2149 		{
2150 			SwNode *pNode;
2151 			sal_Bool bDelete = sal_False;
2152 			if(	(pNode = &aIndx.GetNode())->IsTxtNode() )
2153 			{
2154 				SwTxtNode *pNd = (SwTxtNode*)pNode;
2155 				if( pNd->HasSwAttrSet() )
2156 					pNd->ResetAttr( RES_PAGEDESC, RES_BREAK );
2157 				if( bImpress )
2158 				{
2159 					SwTxtFmtColl* pMyColl = pNd->GetTxtColl();
2160 					//sal_uInt16 nHeadLine = static_cast<sal_uInt16>(pMyColl->GetOutlineLevel()==NO_NUMBERING ?//#outlinelevel,zhaojianwei
2161                     const sal_uInt16 nHeadLine = static_cast<sal_uInt16>(
2162                                 !pMyColl->IsAssignedToListLevelOfOutlineStyle() //<-end,zhaojianwei
2163                                 ? RES_POOLCOLL_HEADLINE2
2164                                 : RES_POOLCOLL_HEADLINE1 );
2165 					pMyColl = pExtDoc->GetTxtCollFromPool( nHeadLine );
2166 					pNd->ChgFmtColl( pMyColl );
2167 				}
2168 				if( !pNd->Len() &&
2169 					pNd->StartOfSectionIndex()+2 < pNd->EndOfSectionIndex() )
2170 				{
2171 					bDelete = sal_True;
2172 					pExtDoc->GetNodes().Delete( aIndx );
2173 				}
2174 			}
2175 			if( !bDelete )
2176 				++aIndx;
2177 		}
2178 		::EndProgress( GetDocShell() );
2179 	}
2180 }
2181 
2182 	// don't delete the visible content from the document, like e.g.,
2183 	// hidden sections, hidden paragraphs
RemoveInvisibleContent()2184 bool SwDoc::RemoveInvisibleContent()
2185 {
2186 	sal_Bool bRet = sal_False;
2187 	GetIDocumentUndoRedo().StartUndo( UNDO_UI_DELETE_INVISIBLECNTNT, NULL );
2188 
2189 	{
2190 		SwTxtNode* pTxtNd;
2191         SwIterator<SwFmtFld,SwFieldType> aIter( *GetSysFldType( RES_HIDDENPARAFLD ) );
2192         for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
2193         {
2194 			if( pFmtFld->GetTxtFld() &&
2195 				0 != ( pTxtNd = (SwTxtNode*)pFmtFld->GetTxtFld()->GetpTxtNode() ) &&
2196                 pTxtNd->GetpSwpHints() && pTxtNd->HasHiddenParaField() &&
2197 				&pTxtNd->GetNodes() == &GetNodes() )
2198 			{
2199 				bRet = sal_True;
2200                 SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() );
2201 
2202                 // Remove hidden paragraph or delete contents:
2203                 // Delete contents if
2204                 // 1. removing the paragraph would result in an empty section or
2205                 // 2. if the paragraph is the last paragraph in the section and
2206                 //    there is no paragraph in front of the paragraph:
2207                 if ( ( 2 == pTxtNd->EndOfSectionIndex() - pTxtNd->StartOfSectionIndex() ) ||
2208                      ( 1 == pTxtNd->EndOfSectionIndex() - pTxtNd->GetIndex() &&
2209                        !GetNodes()[ pTxtNd->GetIndex() - 1 ]->GetTxtNode() ) )
2210                 {
2211                     DeleteRange( aPam );
2212                 }
2213                 else
2214                 {
2215                     aPam.DeleteMark();
2216                     DelFullPara( aPam );
2217                 }
2218             }
2219         }
2220 	}
2221 
2222     //
2223     // Remove any hidden paragraph (hidden text attribute)
2224     //
2225     for( sal_uLong n = GetNodes().Count(); n; )
2226     {
2227         SwTxtNode* pTxtNd = GetNodes()[ --n ]->GetTxtNode();
2228         if ( pTxtNd )
2229         {
2230             bool bRemoved = false;
2231             SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() );
2232             if ( pTxtNd->HasHiddenCharAttribute( true ) )
2233             {
2234                 bRemoved = sal_True;
2235                 bRet = sal_True;
2236 
2237                 // Remove hidden paragraph or delete contents:
2238                 // Delete contents if
2239                 // 1. removing the paragraph would result in an empty section or
2240                 // 2. if the paragraph is the last paragraph in the section and
2241                 //    there is no paragraph in front of the paragraph:
2242 
2243                 if ( ( 2 == pTxtNd->EndOfSectionIndex() - pTxtNd->StartOfSectionIndex() ) ||
2244                      ( 1 == pTxtNd->EndOfSectionIndex() - pTxtNd->GetIndex() &&
2245                        !GetNodes()[ pTxtNd->GetIndex() - 1 ]->GetTxtNode() ) )
2246                 {
2247                     DeleteRange( aPam );
2248                 }
2249                 else
2250                 {
2251                     aPam.DeleteMark();
2252 					DelFullPara( aPam );
2253 				}
2254             }
2255             else if ( pTxtNd->HasHiddenCharAttribute( false ) )
2256             {
2257                 bRemoved = sal_True;
2258                 bRet = sal_True;
2259                 SwScriptInfo::DeleteHiddenRanges( *pTxtNd );
2260             }
2261 
2262             // --> FME 2006-01-11 #120473#
2263             // Footnotes/Frames may have been removed, therefore we have
2264             // to reset n:
2265             if ( bRemoved )
2266                 n = aPam.GetPoint()->nNode.GetIndex();
2267             // <--
2268         }
2269     }
2270 
2271 	{
2272 		// now delete/empty all hidden sections
2273 		SwSectionFmts aSectFmts;
2274 		SwSectionFmts& rSectFmts = GetSections();
2275 		sal_uInt16 n;
2276 
2277 		for( n = rSectFmts.Count(); n; )
2278 		{
2279 			SwSectionFmt* pSectFmt = rSectFmts[ --n ];
2280 		    // don't add sections in Undo/Redo
2281             if( !pSectFmt->IsInNodesArr())
2282                 continue;
2283 			SwSection* pSect = pSectFmt->GetSection();
2284 			if( pSect->CalcHiddenFlag() )
2285 			{
2286 				SwSection* pParent = pSect, *pTmp;
2287 				while( 0 != (pTmp = pParent->GetParent() ))
2288 				{
2289 					if( pTmp->IsHiddenFlag() )
2290 						pSect = pTmp;
2291 					pParent = pTmp;
2292 				}
2293 
2294 				if( USHRT_MAX == aSectFmts.GetPos( pSect->GetFmt() ) )
2295 					aSectFmts.Insert( pSect->GetFmt(), 0 );
2296 			}
2297 			if( pSect->GetCondition().Len() )
2298             {
2299                 SwSectionData aSectionData( *pSect );
2300                 aSectionData.SetCondition( aEmptyStr );
2301                 aSectionData.SetHidden( false );
2302                 UpdateSection( n, aSectionData );
2303             }
2304         }
2305 
2306 		if( 0 != ( n = aSectFmts.Count() ))
2307 		{
2308 			while( n )
2309 			{
2310 				SwSectionFmt* pSectFmt = aSectFmts[ --n ];
2311 				SwSectionNode* pSectNd = pSectFmt->GetSectionNode();
2312 				if( pSectNd )
2313 				{
2314 					bRet = sal_True;
2315 					SwPaM aPam( *pSectNd );
2316 
2317                     if( pSectNd->StartOfSectionNode()->StartOfSectionIndex() ==
2318 						pSectNd->GetIndex() - 1 &&
2319                         pSectNd->StartOfSectionNode()->EndOfSectionIndex() ==
2320 						pSectNd->EndOfSectionIndex() + 1 )
2321 					{
2322 						// delete only the content
2323 						SwCntntNode* pCNd = GetNodes().GoNext(
2324 												&aPam.GetPoint()->nNode );
2325 						aPam.GetPoint()->nContent.Assign( pCNd, 0 );
2326 						aPam.SetMark();
2327 						aPam.GetPoint()->nNode = *pSectNd->EndOfSectionNode();
2328 						pCNd = GetNodes().GoPrevious(
2329 												&aPam.GetPoint()->nNode );
2330 						aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
2331 
2332                         DeleteRange( aPam );
2333                     }
2334 					else
2335 					{
2336 						// delete the complete section
2337 						aPam.SetMark();
2338 						aPam.GetPoint()->nNode = *pSectNd->EndOfSectionNode();
2339 						DelFullPara( aPam );
2340 					}
2341 
2342 				}
2343 			}
2344 			aSectFmts.Remove( 0, aSectFmts.Count() );
2345 		}
2346 	}
2347 
2348 	if( bRet )
2349 		SetModified();
2350     GetIDocumentUndoRedo().EndUndo( UNDO_UI_DELETE_INVISIBLECNTNT, NULL );
2351 	return bRet;
2352 }
2353 /*-- 25.08.2010 14:18:12---------------------------------------------------
2354 
2355   -----------------------------------------------------------------------*/
HasInvisibleContent() const2356 bool SwDoc::HasInvisibleContent() const
2357 {
2358     sal_Bool bRet = sal_False;
2359 
2360     SwClientIter aIter( *GetSysFldType( RES_HIDDENPARAFLD ) );
2361     if( aIter.First( TYPE( SwFmtFld ) ) )
2362         bRet = sal_True;
2363 
2364     //
2365     // Search for any hidden paragraph (hidden text attribute)
2366     //
2367     if( ! bRet )
2368     {
2369         for( sal_uLong n = GetNodes().Count(); !bRet && (n > 0); )
2370         {
2371             SwTxtNode* pTxtNd = GetNodes()[ --n ]->GetTxtNode();
2372             if ( pTxtNd )
2373             {
2374                 SwPaM aPam( *pTxtNd, 0, *pTxtNd, pTxtNd->GetTxt().Len() );
2375                 if( pTxtNd->HasHiddenCharAttribute( true ) || ( pTxtNd->HasHiddenCharAttribute( false ) ) )
2376                 {
2377                     bRet = sal_True;
2378                 }
2379             }
2380         }
2381     }
2382 
2383     if( ! bRet )
2384     {
2385         const SwSectionFmts& rSectFmts = GetSections();
2386         sal_uInt16 n;
2387 
2388         for( n = rSectFmts.Count(); !bRet && (n > 0); )
2389         {
2390             SwSectionFmt* pSectFmt = rSectFmts[ --n ];
2391             // don't add sections in Undo/Redo
2392             if( !pSectFmt->IsInNodesArr())
2393                 continue;
2394             SwSection* pSect = pSectFmt->GetSection();
2395             if( pSect->IsHidden() )
2396                 bRet = sal_True;
2397         }
2398     }
2399     return bRet;
2400 }
2401 
RestoreInvisibleContent()2402 bool SwDoc::RestoreInvisibleContent()
2403 {
2404     bool bRet = false;
2405     SwUndoId nLastUndoId(UNDO_EMPTY);
2406     if (GetIDocumentUndoRedo().GetLastUndoInfo(0, & nLastUndoId)
2407         && (UNDO_UI_DELETE_INVISIBLECNTNT == nLastUndoId))
2408     {
2409         GetIDocumentUndoRedo().Undo();
2410         GetIDocumentUndoRedo().ClearRedo();
2411         bRet = true;
2412     }
2413     return bRet;
2414 }
2415 
2416 /*-- 11.06.2004 08:34:04---------------------------------------------------
2417 
2418   -----------------------------------------------------------------------*/
ConvertFieldsToText()2419 sal_Bool SwDoc::ConvertFieldsToText()
2420 {
2421     sal_Bool bRet = sal_False;
2422     LockExpFlds();
2423     GetIDocumentUndoRedo().StartUndo( UNDO_UI_REPLACE, NULL );
2424 
2425     const SwFldTypes* pMyFldTypes = GetFldTypes();
2426     sal_uInt16 nCount = pMyFldTypes->Count();
2427     //go backward, field types are removed
2428     for(sal_uInt16 nType = nCount; nType > 0; --nType)
2429     {
2430         const SwFieldType *pCurType = pMyFldTypes->GetObject(nType - 1);
2431 
2432         if ( RES_POSTITFLD == pCurType->Which() )
2433             continue;
2434 
2435         SwIterator<SwFmtFld,SwFieldType> aIter( *pCurType );
2436         ::std::vector<const SwFmtFld*> aFieldFmts;
2437         for( SwFmtFld* pCurFldFmt = aIter.First(); pCurFldFmt; pCurFldFmt = aIter.Next() )
2438             aFieldFmts.push_back(pCurFldFmt);
2439 
2440         ::std::vector<const SwFmtFld*>::iterator aBegin = aFieldFmts.begin();
2441         ::std::vector<const SwFmtFld*>::iterator aEnd = aFieldFmts.end();
2442         while(aBegin != aEnd)
2443         {
2444             const SwTxtFld *pTxtFld = (*aBegin)->GetTxtFld();
2445             // skip fields that are currently not in the document
2446             // e.g. fields in undo or redo array
2447 
2448             sal_Bool bSkip = !pTxtFld ||
2449                          !pTxtFld->GetpTxtNode()->GetNodes().IsDocNodes();
2450 
2451             if (!bSkip)
2452             {
2453                 sal_Bool bInHeaderFooter = IsInHeaderFooter(SwNodeIndex(*pTxtFld->GetpTxtNode()));
2454                 const SwFmtFld& rFmtFld = pTxtFld->GetFmtFld();
2455                 const SwField*  pField = rFmtFld.GetField();
2456 
2457                 //#i55595# some fields have to be excluded in headers/footers
2458                 sal_uInt16 nWhich = pField->GetTyp()->Which();
2459                 if(!bInHeaderFooter ||
2460                         (nWhich != RES_PAGENUMBERFLD &&
2461                         nWhich != RES_CHAPTERFLD &&
2462                         nWhich != RES_GETEXPFLD&&
2463                         nWhich != RES_SETEXPFLD&&
2464                         nWhich != RES_INPUTFLD&&
2465                         nWhich != RES_REFPAGEGETFLD&&
2466                         nWhich != RES_REFPAGESETFLD))
2467                 {
2468                     String sText = pField->ExpandField(true);
2469                     //database fields should not convert their command into text
2470                     if( RES_DBFLD == pCurType->Which() && !static_cast<const SwDBField*>(pField)->IsInitialized())
2471                         sText.Erase();
2472 
2473                     //now remove the field and insert the string
2474                     SwPaM aPam1(*pTxtFld->GetpTxtNode(), *pTxtFld->GetStart());
2475                     aPam1.Move();
2476                     //insert first to keep the field's attributes
2477                     InsertString( aPam1, sText );
2478                     SwPaM aPam2(*pTxtFld->GetpTxtNode(), *pTxtFld->GetStart());
2479                     aPam2.SetMark();
2480                     aPam2.Move();
2481                     DeleteAndJoin(aPam2);//remove the field
2482                 }
2483             }
2484             ++aBegin;
2485         }
2486     }
2487 
2488     if( bRet )
2489         SetModified();
2490     GetIDocumentUndoRedo().EndUndo( UNDO_UI_REPLACE, NULL );
2491     UnlockExpFlds();
2492     return bRet;
2493 
2494 }
2495 
IsVisibleLinks() const2496 bool SwDoc::IsVisibleLinks() const
2497 {
2498 	return mbVisibleLinks;
2499 }
2500 
SetVisibleLinks(bool bFlag)2501 void SwDoc::SetVisibleLinks(bool bFlag)
2502 {
2503 	mbVisibleLinks = bFlag;
2504 }
2505 
GetLinkManager()2506 sfx2::LinkManager& SwDoc::GetLinkManager()
2507 {
2508 	return *pLinkMgr;
2509 }
2510 
GetLinkManager() const2511 const sfx2::LinkManager& SwDoc::GetLinkManager() const
2512 {
2513 	return *pLinkMgr;
2514 }
2515 
SetLinksUpdated(const bool bNewLinksUpdated)2516 void SwDoc::SetLinksUpdated(const bool bNewLinksUpdated)
2517 {
2518 	mbLinksUpdated = bNewLinksUpdated;
2519 }
2520 
LinksUpdated() const2521 bool SwDoc::LinksUpdated() const
2522 {
2523 	return mbLinksUpdated;
2524 }
2525 
2526 	// embed all local links (sections/graphics)
lcl_FindNextRemovableLink(const::sfx2::SvBaseLinks & rLinks,sfx2::LinkManager & rLnkMgr)2527 ::sfx2::SvBaseLink* lcl_FindNextRemovableLink( const ::sfx2::SvBaseLinks& rLinks, sfx2::LinkManager& rLnkMgr )
2528 {
2529     for( sal_uInt16 n = 0; n < rLinks.Count(); ++n )
2530     {
2531         ::sfx2::SvBaseLink* pLnk = &(*rLinks[ n ]);
2532         if( pLnk &&
2533             ( OBJECT_CLIENT_GRF == pLnk->GetObjType() ||
2534               OBJECT_CLIENT_FILE == pLnk->GetObjType() ) &&
2535             pLnk->ISA( SwBaseLink ) )
2536         {
2537                 ::sfx2::SvBaseLinkRef xLink = pLnk;
2538 
2539                 String sFName;
2540                 rLnkMgr.GetDisplayNames( xLink, 0, &sFName, 0, 0 );
2541 
2542                 INetURLObject aURL( sFName );
2543                 if( INET_PROT_FILE == aURL.GetProtocol() ||
2544                     INET_PROT_CID == aURL.GetProtocol() )
2545                     return pLnk;
2546         }
2547     }
2548     return 0;
2549 }
EmbedAllLinks()2550 bool SwDoc::EmbedAllLinks()
2551 {
2552 	sal_Bool bRet = sal_False;
2553 	sfx2::LinkManager& rLnkMgr = GetLinkManager();
2554     const ::sfx2::SvBaseLinks& rLinks = rLnkMgr.GetLinks();
2555     if( rLinks.Count() )
2556 	{
2557         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
2558 
2559         ::sfx2::SvBaseLink* pLnk = 0;
2560         while( 0 != (pLnk = lcl_FindNextRemovableLink( rLinks, rLnkMgr ) ) )
2561 		{
2562             ::sfx2::SvBaseLinkRef xLink = pLnk;
2563             // tell the link that it will be cleared!
2564             xLink->Closed();
2565 
2566             // in the case a link was not deregistered
2567             if( xLink.Is() )
2568                 rLnkMgr.Remove( xLink );
2569 
2570             bRet = sal_True;
2571 		}
2572 
2573         GetIDocumentUndoRedo().DelAllUndoObj();
2574 		SetModified();
2575 	}
2576 	return bRet;
2577 }
2578 
2579 /*--------------------------------------------------------------------
2580 	Description:
2581  --------------------------------------------------------------------*/
2582 
IsInsTblFormatNum() const2583 sal_Bool SwDoc::IsInsTblFormatNum() const
2584 {
2585 	return SW_MOD()->IsInsTblFormatNum(get(IDocumentSettingAccess::HTML_MODE));
2586 }
2587 
IsInsTblChangeNumFormat() const2588 sal_Bool SwDoc::IsInsTblChangeNumFormat() const
2589 {
2590 	return SW_MOD()->IsInsTblChangeNumFormat(get(IDocumentSettingAccess::HTML_MODE));
2591 }
2592 
2593 /*--------------------------------------------------------------------
2594 	Description:
2595  --------------------------------------------------------------------*/
2596 
IsInsTblAlignNum() const2597 sal_Bool SwDoc::IsInsTblAlignNum() const
2598 {
2599 	return SW_MOD()->IsInsTblAlignNum(get(IDocumentSettingAccess::HTML_MODE));
2600 }
2601 
2602         // set the InsertDB as table Undo to:
AppendUndoForInsertFromDB(const SwPaM & rPam,sal_Bool bIsTable)2603 void SwDoc::AppendUndoForInsertFromDB( const SwPaM& rPam, sal_Bool bIsTable )
2604 {
2605 	if( bIsTable )
2606 	{
2607 		const SwTableNode* pTblNd = rPam.GetPoint()->nNode.GetNode().FindTableNode();
2608 		if( pTblNd )
2609 		{
2610 			SwUndoCpyTbl* pUndo = new SwUndoCpyTbl;
2611 			pUndo->SetTableSttIdx( pTblNd->GetIndex() );
2612             GetIDocumentUndoRedo().AppendUndo( pUndo );
2613         }
2614     }
2615 	else if( rPam.HasMark() )
2616 	{
2617 		SwUndoCpyDoc* pUndo = new SwUndoCpyDoc( rPam );
2618 		pUndo->SetInsertRange( rPam, sal_False );
2619         GetIDocumentUndoRedo().AppendUndo( pUndo );
2620     }
2621 }
2622 
ChgTOX(SwTOXBase & rTOX,const SwTOXBase & rNew)2623 void SwDoc::ChgTOX(SwTOXBase & rTOX, const SwTOXBase & rNew)
2624 {
2625     if (GetIDocumentUndoRedo().DoesUndo())
2626     {
2627         GetIDocumentUndoRedo().DelAllUndoObj();
2628 
2629         SwUndo * pUndo = new SwUndoTOXChange(&rTOX, rNew);
2630 
2631         GetIDocumentUndoRedo().AppendUndo(pUndo);
2632     }
2633 
2634     rTOX = rNew;
2635 
2636     if (rTOX.ISA(SwTOXBaseSection))
2637     {
2638         static_cast<SwTOXBaseSection &>(rTOX).Update();
2639         static_cast<SwTOXBaseSection &>(rTOX).UpdatePageNum();
2640     }
2641 }
2642 
2643 // #111827#
GetPaMDescr(const SwPaM & rPam) const2644 String SwDoc::GetPaMDescr(const SwPaM & rPam) const
2645 {
2646     String aResult;
2647     bool bOK = false;
2648 
2649     if (rPam.GetNode(sal_True) == rPam.GetNode(sal_False))
2650     {
2651         SwTxtNode * pTxtNode = rPam.GetNode(sal_True)->GetTxtNode();
2652 
2653         if (0 != pTxtNode)
2654         {
2655             xub_StrLen nStart = rPam.Start()->nContent.GetIndex();
2656             xub_StrLen nEnd = rPam.End()->nContent.GetIndex();
2657 
2658             aResult += String(SW_RES(STR_START_QUOTE));
2659             aResult += ShortenString(pTxtNode->GetTxt().
2660                                      Copy(nStart, nEnd - nStart),
2661                                      nUndoStringLength,
2662                                      String(SW_RES(STR_LDOTS)));
2663             aResult += String(SW_RES(STR_END_QUOTE));
2664 
2665             bOK = true;
2666         }
2667     }
2668     else if (0 != rPam.GetNode(sal_True))
2669     {
2670         if (0 != rPam.GetNode(sal_False))
2671             aResult += String(SW_RES(STR_PARAGRAPHS));
2672 
2673         bOK = true;
2674     }
2675 
2676     if (! bOK)
2677         aResult += String("??", RTL_TEXTENCODING_ASCII_US);
2678 
2679     return aResult;
2680 }
2681 
GetFieldAtPos(const SwPosition & rPos)2682 SwField * SwDoc::GetFieldAtPos(const SwPosition & rPos)
2683 {
2684     SwTxtFld * const pAttr = GetTxtFldAtPos(rPos);
2685 
2686     return (pAttr) ? const_cast<SwField *>( pAttr->GetFmtFld().GetField() ) : 0;
2687 }
2688 
GetTxtFldAtPos(const SwPosition & rPos)2689 SwTxtFld * SwDoc::GetTxtFldAtPos(const SwPosition & rPos)
2690 {
2691     SwTxtNode * const pNode = rPos.nNode.GetNode().GetTxtNode();
2692 
2693     return (pNode != NULL)
2694         ? pNode->GetFldTxtAttrAt( rPos.nContent.GetIndex(), true )
2695         : 0;
2696 }
2697 
ContainsHiddenChars() const2698 bool SwDoc::ContainsHiddenChars() const
2699 {
2700     for( sal_uLong n = GetNodes().Count(); n; )
2701     {
2702         SwNode* pNd = GetNodes()[ --n ];
2703         if ( ND_TEXTNODE == pNd->GetNodeType() &&
2704              ((SwTxtNode*)pNd)->HasHiddenCharAttribute( false ) )
2705             return true;
2706     }
2707 
2708     return false;
2709 }
2710 
CreateUnoCrsr(const SwPosition & rPos,sal_Bool bTblCrsr)2711 SwUnoCrsr* SwDoc::CreateUnoCrsr( const SwPosition& rPos, sal_Bool bTblCrsr )
2712 {
2713 	SwUnoCrsr* pNew;
2714 	if( bTblCrsr )
2715 		pNew = new SwUnoTableCrsr( rPos );
2716 	else
2717 		pNew = new SwUnoCrsr( rPos );
2718 
2719 	pUnoCrsrTbl->Insert( pNew, pUnoCrsrTbl->Count() );
2720 	return pNew;
2721 }
2722 
ChkCondColls()2723 void SwDoc::ChkCondColls()
2724 {
2725      for (sal_uInt16 n = 0; n < pTxtFmtCollTbl->Count(); n++)
2726      {
2727         SwTxtFmtColl *pColl = (*pTxtFmtCollTbl)[n];
2728         if (RES_CONDTXTFMTCOLL == pColl->Which())
2729             pColl->CallSwClientNotify( SwAttrHint(RES_CONDTXTFMTCOLL) );
2730      }
2731 }
2732 
2733 #ifdef FUTURE_VBA
2734 uno::Reference< script::vba::XVBAEventProcessor >
GetVbaEventProcessor()2735 SwDoc::GetVbaEventProcessor()
2736 {
2737 	if( !mxVbaEvents.is() && pDocShell && ooo::vba::isAlienWordDoc( *pDocShell ) )
2738 	{
2739         try
2740         {
2741             uno::Reference< frame::XModel > xModel( pDocShell->GetModel(), uno::UNO_SET_THROW );
2742             uno::Sequence< uno::Any > aArgs(1);
2743             aArgs[0] <<= xModel;
2744             mxVbaEvents.set( ooo::vba::createVBAUnoAPIServiceWithArgs( pDocShell, "com.sun.star.script.vba.VBATextEventProcessor" , aArgs ), uno::UNO_QUERY_THROW );
2745         }
2746         catch( uno::Exception& )
2747         {
2748         }
2749 	}
2750 	return mxVbaEvents;
2751 }
2752 #endif
2753 
setExternalData(::sw::tExternalDataType eType,::sw::tExternalDataPointer pPayload)2754 void SwDoc::setExternalData(::sw::tExternalDataType eType,
2755                             ::sw::tExternalDataPointer pPayload)
2756 {
2757 	m_externalData[eType] = pPayload;
2758 }
2759 
getExternalData(::sw::tExternalDataType eType)2760 ::sw::tExternalDataPointer SwDoc::getExternalData(::sw::tExternalDataType eType)
2761 {
2762 	return m_externalData[eType];
2763 }
2764 
2765