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