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