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