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