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