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 <cmdid.h> 26 #include <hintids.hxx> 27 #include <vcl/virdev.hxx> 28 #include <svx/svdmodel.hxx> 29 #include <editeng/ulspitem.hxx> 30 #include <editeng/lrspitem.hxx> 31 #include <editeng/paperinf.hxx> 32 #include "editeng/frmdiritem.hxx" 33 #include <tools/urlobj.hxx> 34 #include <sfx2/docfile.hxx> 35 #include <sfx2/printer.hxx> 36 #include <sfx2/bindings.hxx> 37 #include <sfx2/dispatch.hxx> 38 #include <unotools/localedatawrapper.hxx> 39 #include <com/sun/star/document/PrinterIndependentLayout.hpp> 40 #include <fmtfsize.hxx> 41 #include <fmthdft.hxx> 42 #include <fmtcntnt.hxx> 43 #include <fmtpdsc.hxx> 44 #include <ftninfo.hxx> 45 #include <fesh.hxx> 46 #include <ndole.hxx> 47 #include <mdiexp.hxx> 48 #include <doc.hxx> 49 #include <IDocumentUndoRedo.hxx> 50 #include <docary.hxx> 51 #include <pagefrm.hxx> // for DelPageDesc 52 #include <rootfrm.hxx> // for DelPageDesc 53 #include <ndtxt.hxx> 54 #include <frmtool.hxx> 55 #include <pagedesc.hxx> 56 #include <poolfmt.hxx> 57 #include <docsh.hxx> 58 #include <ndindex.hxx> 59 #include <ftnidx.hxx> 60 #include <fmtftn.hxx> 61 #include <txtftn.hxx> 62 #include <fntcache.hxx> 63 #include <viewsh.hxx> 64 #include <viewopt.hxx> 65 #include <fldbas.hxx> 66 #include <swwait.hxx> 67 #include <GetMetricVal.hxx> 68 #include <unotools/syslocale.hxx> 69 #include <statstr.hrc> 70 #include <switerator.hxx> 71 #include <hints.hxx> 72 #include <SwUndoPageDesc.hxx> 73 #include <pagedeschint.hxx> 74 #include <tgrditem.hxx> 75 #include <drawdoc.hxx> 76 77 using namespace com::sun::star; 78 79 static void lcl_DefaultPageFmt( sal_uInt16 nPoolFmtId, 80 SwFrmFmt &rFmt1, 81 SwFrmFmt &rFmt2 ) 82 { 83 // --> FME 2005-01-21 #i41075# Printer on demand 84 // This function does not require a printer anymore. 85 // The default page size is obtained from the application 86 // locale 87 // <-- 88 89 SwFmtFrmSize aFrmSize( ATT_FIX_SIZE ); 90 const Size aPhysSize = SvxPaperInfo::GetDefaultPaperSize(); 91 aFrmSize.SetSize( aPhysSize ); 92 93 // Prepare for default margins. 94 // Margins have a default minimum size. 95 // If the printer gives a larger margin, then it's OK as well. 96 // MIB 06/25/2002, #99397#: The HTML page desc had A4 as page size 97 // always. This has been changed to take the page size from the printer. 98 // Unfortunately, the margins of the HTML page desc are smaller than 99 // the margins used here in general, so one extra case is required. 100 // In the long term, this needs to be changed to always keep the 101 // margins from the page desc. 102 sal_Int32 nMinTop, nMinBottom, nMinLeft, nMinRight; 103 if( RES_POOLPAGE_HTML == nPoolFmtId ) 104 { 105 nMinRight = nMinTop = nMinBottom = GetMetricVal( CM_1 ); 106 nMinLeft = nMinRight * 2; 107 } 108 else if( MEASURE_METRIC == SvtSysLocale().GetLocaleData().getMeasurementSystemEnum() ) 109 { 110 nMinTop = nMinBottom = nMinLeft = nMinRight = 1134; // 2 centimeters 111 } 112 else 113 { 114 nMinTop = nMinBottom = 1440; //al la WW: 1 Inch 115 nMinLeft = nMinRight = 1800; // 1,25 Inch 116 } 117 118 // set the margins 119 SvxLRSpaceItem aLR( RES_LR_SPACE ); 120 SvxULSpaceItem aUL( RES_UL_SPACE ); 121 122 aUL.SetUpper( (sal_uInt16)nMinTop ); 123 aUL.SetLower( (sal_uInt16)nMinBottom ); 124 aLR.SetRight( nMinRight ); 125 aLR.SetLeft( nMinLeft ); 126 127 rFmt1.SetFmtAttr( aFrmSize ); 128 rFmt1.SetFmtAttr( aLR ); 129 rFmt1.SetFmtAttr( aUL ); 130 131 rFmt2.SetFmtAttr( aFrmSize ); 132 rFmt2.SetFmtAttr( aLR ); 133 rFmt2.SetFmtAttr( aUL ); 134 } 135 136 /************************************************************************* 137 |* 138 |* SwDoc::ChgPageDesc() 139 |* 140 |* Created MA 25. Jan. 93 141 |* Last change MA 01. Mar. 95 142 |* 143 |*************************************************************************/ 144 145 void lcl_DescSetAttr( const SwFrmFmt &rSource, SwFrmFmt &rDest, 146 const sal_Bool bPage = sal_True ) 147 { 148 /////////////// !!!!!!!!!!!!!!!! 149 //JP 03.03.99: 150 // Actually the Intersect from ItemSet should be used here but that doesn't 151 // work correctly when you have different WhichRanges. 152 /////////////// !!!!!!!!!!!!!!!! 153 // Take over the interesting attributes. 154 sal_uInt16 __READONLY_DATA aIdArr[] = { 155 RES_FRM_SIZE, RES_UL_SPACE, // [83..86 156 RES_BACKGROUND, RES_SHADOW, // [99..101 157 RES_COL, RES_COL, // [103 158 RES_TEXTGRID, RES_TEXTGRID, // [109 159 RES_FRAMEDIR, RES_FRAMEDIR, // [114 160 RES_HEADER_FOOTER_EAT_SPACING, RES_HEADER_FOOTER_EAT_SPACING, // [115 161 RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER, // [143 162 163 //UUUU take over DrawingLayer FillStyles 164 XATTR_FILL_FIRST, XATTR_FILL_LAST, // [1014 165 166 0}; 167 168 const SfxPoolItem* pItem; 169 for( sal_uInt16 n = 0; aIdArr[ n ]; n += 2 ) 170 { 171 for( sal_uInt16 nId = aIdArr[ n ]; nId <= aIdArr[ n+1]; ++nId ) 172 { 173 // bPage == true: 174 // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING 175 // bPage == false: 176 // All in aIdArr except from RES_COL and RES_PAPER_BIN: 177 bool bExecuteId(true); 178 179 if(bPage) 180 { 181 // When Page 182 switch(nId) 183 { 184 // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING 185 case RES_HEADER_FOOTER_EAT_SPACING: 186 //UUUU take out SvxBrushItem; it's the result of the fallback 187 // at SwFmt::GetItemState and not really in state SFX_ITEM_SET 188 case RES_BACKGROUND: 189 bExecuteId = false; 190 break; 191 default: 192 break; 193 } 194 } 195 else 196 { 197 // When not Page 198 switch(nId) 199 { 200 // When not Page: All in aIdArr except from RES_COL and RES_PAPER_BIN: 201 case RES_COL: 202 case RES_PAPER_BIN: 203 bExecuteId = false; 204 break; 205 default: 206 break; 207 } 208 } 209 210 if(bExecuteId) 211 { 212 if(SFX_ITEM_SET == rSource.GetItemState(nId,sal_False,&pItem)) 213 { 214 rDest.SetFmtAttr(*pItem); 215 } 216 else 217 { 218 rDest.ResetFmtAttr(nId); 219 } 220 } 221 } 222 } 223 224 // transfer also the Pool-, Help-ID's 225 rDest.SetPoolFmtId( rSource.GetPoolFmtId() ); 226 rDest.SetPoolHelpId( rSource.GetPoolHelpId() ); 227 rDest.SetPoolHlpFileId( rSource.GetPoolHlpFileId() ); 228 } 229 230 231 void SwDoc::ChgPageDesc( sal_uInt16 i, const SwPageDesc &rChged ) 232 { 233 ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." ); 234 235 SwPageDesc *pDesc = aPageDescs[i]; 236 SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219 237 238 if (GetIDocumentUndoRedo().DoesUndo()) 239 { 240 SwUndo *const pUndo(new SwUndoPageDesc(*pDesc, rChged, this)); 241 GetIDocumentUndoRedo().AppendUndo(pUndo); 242 } 243 ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo()); 244 245 // first mirror if necessary 246 if ( rChged.GetUseOn() == nsUseOnPage::PD_MIRROR ) 247 ((SwPageDesc&)rChged).Mirror(); 248 else 249 // otherwise transfer the values from Master to Left. 250 ::lcl_DescSetAttr( ((SwPageDesc&)rChged).GetMaster(), 251 ((SwPageDesc&)rChged).GetLeft() ); 252 253 // take over NumType. 254 if( rChged.GetNumType().GetNumberingType() != pDesc->GetNumType().GetNumberingType() ) 255 { 256 pDesc->SetNumType( rChged.GetNumType() ); 257 // JP 30.03.99: Bug 64121 - tell it to the page number fields 258 // that the numbering format has changed 259 GetSysFldType( RES_PAGENUMBERFLD )->UpdateFlds(); 260 GetSysFldType( RES_REFPAGEGETFLD )->UpdateFlds(); 261 262 // When the numbering type has changed, it's possible that there are QuoVadis/ 263 // ErgoSum texts, that are referring to a changed page, 264 // therefore the foot notes will be invalidated 265 SwFtnIdxs& rFtnIdxs = GetFtnIdxs(); 266 for( sal_uInt16 nPos = 0; nPos < rFtnIdxs.Count(); ++nPos ) 267 { 268 SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ]; 269 const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); 270 pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr()); 271 } 272 } 273 274 // take over the orientation 275 pDesc->SetLandscape( rChged.GetLandscape() ); 276 277 // #i46909# no undo if header or footer changed 278 bool bHeaderFooterChanged = false; 279 280 // align header 281 const SwFmtHeader &rHead = rChged.GetMaster().GetHeader(); 282 if (undoGuard.UndoWasEnabled()) 283 { 284 // #i46909# no undo if header or footer changed 285 // are there changes in the Nodes? 286 const SwFmtHeader &rOldHead = pDesc->GetMaster().GetHeader(); 287 bHeaderFooterChanged |= 288 ( rHead.IsActive() != rOldHead.IsActive() || 289 rChged.IsHeaderShared() != pDesc->IsHeaderShared() ); 290 } 291 pDesc->GetMaster().SetFmtAttr( rHead ); 292 if ( rChged.IsHeaderShared() || !rHead.IsActive() ) 293 { 294 // Left is sharing the Header with the Master 295 pDesc->GetLeft().SetFmtAttr( pDesc->GetMaster().GetHeader() ); 296 } 297 else if ( rHead.IsActive() ) 298 { // Left get an own Header, when the Format hasn't one already. 299 // If it has already one and it refers to the same section like the Right, 300 // then it has to get an own Header. The content will be copied accordingly. 301 302 const SwFmtHeader &rLeftHead = pDesc->GetLeft().GetHeader(); 303 if ( !rLeftHead.IsActive() ) 304 { 305 SwFmtHeader aHead( MakeLayoutFmt( RND_STD_HEADERL, 0 ) ); 306 pDesc->GetLeft().SetFmtAttr( aHead ); 307 // take over further attributes (margins, borders ...) 308 ::lcl_DescSetAttr( *rHead.GetHeaderFmt(), *aHead.GetHeaderFmt(), sal_False); 309 } 310 else 311 { 312 const SwFrmFmt *pRight = rHead.GetHeaderFmt(); 313 const SwFmtCntnt &aRCnt = pRight->GetCntnt(); 314 const SwFmtCntnt &aLCnt = rLeftHead.GetHeaderFmt()->GetCntnt(); 315 if( !aLCnt.GetCntntIdx() ) 316 pDesc->GetLeft().SetFmtAttr( rChged.GetLeft().GetHeader() ); 317 else if( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) ) 318 { 319 SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Header", 320 GetDfltFrmFmt() ); 321 ::lcl_DescSetAttr( *pRight, *pFmt, sal_False ); 322 // The section that refers to the right head attribute will be copied and 323 // the index on the StartNode will be attached into the left head attribute. 324 SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() ); 325 SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwHeaderStartNode ); 326 SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0, 327 *aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() ); 328 aTmp = *pSttNd->EndOfSectionNode(); 329 GetNodes()._Copy( aRange, aTmp, sal_False ); 330 331 pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ) ); 332 pDesc->GetLeft().SetFmtAttr( SwFmtHeader( pFmt ) ); 333 } 334 else 335 ::lcl_DescSetAttr( *pRight, 336 *(SwFrmFmt*)rLeftHead.GetHeaderFmt(), sal_False ); 337 338 } 339 } 340 pDesc->ChgHeaderShare( rChged.IsHeaderShared() ); 341 342 // align footer 343 const SwFmtFooter &rFoot = rChged.GetMaster().GetFooter(); 344 if (undoGuard.UndoWasEnabled()) 345 { 346 // #i46909# no undo if header or footer changed 347 // are there changes in the Nodes? 348 const SwFmtFooter &rOldFoot = pDesc->GetMaster().GetFooter(); 349 bHeaderFooterChanged |= 350 ( rFoot.IsActive() != rOldFoot.IsActive() || 351 rChged.IsFooterShared() != pDesc->IsFooterShared() ); 352 } 353 pDesc->GetMaster().SetFmtAttr( rFoot ); 354 if ( rChged.IsFooterShared() || !rFoot.IsActive() ) 355 // Left is sharing the Footer with the Master 356 pDesc->GetLeft().SetFmtAttr( pDesc->GetMaster().GetFooter() ); 357 else if ( rFoot.IsActive() ) 358 { // Left get an own Footer, when the Format hasn't one already. 359 // If it has already one and it refers to the same section like the Right, 360 // then it has to get an own Footer. The content will be copied accordingly. 361 const SwFmtFooter &rLeftFoot = pDesc->GetLeft().GetFooter(); 362 if ( !rLeftFoot.IsActive() ) 363 { 364 SwFmtFooter aFoot( MakeLayoutFmt( RND_STD_FOOTER, 0 ) ); 365 pDesc->GetLeft().SetFmtAttr( aFoot ); 366 // take over further attributes (margins, borders ...) 367 ::lcl_DescSetAttr( *rFoot.GetFooterFmt(), *aFoot.GetFooterFmt(), sal_False); 368 } 369 else 370 { 371 const SwFrmFmt *pRight = rFoot.GetFooterFmt(); 372 const SwFmtCntnt &aRCnt = pRight->GetCntnt(); 373 const SwFmtCntnt &aLCnt = rLeftFoot.GetFooterFmt()->GetCntnt(); 374 if( !aLCnt.GetCntntIdx() ) 375 pDesc->GetLeft().SetFmtAttr( rChged.GetLeft().GetFooter() ); 376 else if( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) ) 377 { 378 SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Footer", 379 GetDfltFrmFmt() ); 380 ::lcl_DescSetAttr( *pRight, *pFmt, sal_False ); 381 // The section that refers to the right head attribute will be copied and 382 // the index on the StartNode will be attached into the left head attribute. 383 SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() ); 384 SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwFooterStartNode ); 385 SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0, 386 *aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() ); 387 aTmp = *pSttNd->EndOfSectionNode(); 388 GetNodes()._Copy( aRange, aTmp, sal_False ); 389 390 pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ) ); 391 pDesc->GetLeft().SetFmtAttr( SwFmtFooter( pFmt ) ); 392 } 393 else 394 ::lcl_DescSetAttr( *pRight, 395 *(SwFrmFmt*)rLeftFoot.GetFooterFmt(), sal_False ); 396 } 397 } 398 pDesc->ChgFooterShare( rChged.IsFooterShared() ); 399 400 if ( pDesc->GetName() != rChged.GetName() ) 401 pDesc->SetName( rChged.GetName() ); 402 403 // this will trigger a RegisterChange if necessary 404 pDesc->SetRegisterFmtColl( rChged.GetRegisterFmtColl() ); 405 406 // when UseOn or Follow are changed, then the paragraphs have to know this 407 sal_Bool bUseOn = sal_False; 408 sal_Bool bFollow = sal_False; 409 if ( pDesc->GetUseOn() != rChged.GetUseOn() ) 410 { pDesc->SetUseOn( rChged.GetUseOn() ); 411 bUseOn = sal_True; 412 } 413 if ( pDesc->GetFollow() != rChged.GetFollow() ) 414 { if ( rChged.GetFollow() == &rChged ) 415 { if ( pDesc->GetFollow() != pDesc ) 416 { pDesc->SetFollow( pDesc ); 417 bFollow = sal_True; 418 } 419 } 420 else 421 { pDesc->SetFollow( rChged.pFollow ); 422 bFollow = sal_True; 423 } 424 } 425 426 if ( (bUseOn || bFollow) && pTmpRoot) 427 // notify Layot! 428 { 429 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 430 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080304 431 } 432 433 // now take over the page attributes 434 ::lcl_DescSetAttr( rChged.GetMaster(), pDesc->GetMaster() ); 435 ::lcl_DescSetAttr( rChged.GetLeft(), pDesc->GetLeft() ); 436 437 // when FootnotesInfo are changed, then trigger the pages 438 if( !(pDesc->GetFtnInfo() == rChged.GetFtnInfo()) ) 439 { 440 pDesc->SetFtnInfo( rChged.GetFtnInfo() ); 441 SwMsgPoolItem aInfo( RES_PAGEDESC_FTNINFO ); 442 { 443 pDesc->GetMaster().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) ); 444 } 445 { 446 pDesc->GetLeft().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) ); 447 } 448 } 449 SetModified(); 450 451 // #i46909# no undo if header or footer changed 452 if( bHeaderFooterChanged ) 453 { 454 GetIDocumentUndoRedo().DelAllUndoObj(); 455 } 456 457 SfxBindings* pBindings = 458 ( GetDocShell() && GetDocShell()->GetDispatcher() ) ? GetDocShell()->GetDispatcher()->GetBindings() : 0; 459 if ( pBindings ) 460 { 461 pBindings->Invalidate( SID_ATTR_PAGE_COLUMN ); 462 pBindings->Invalidate( SID_ATTR_PAGE ); 463 pBindings->Invalidate( SID_ATTR_PAGE_SIZE ); 464 pBindings->Invalidate( SID_ATTR_PAGE_ULSPACE ); 465 pBindings->Invalidate( SID_ATTR_PAGE_LRSPACE ); 466 } 467 468 } 469 470 /************************************************************************* 471 |* 472 |* SwDoc::DelPageDesc() 473 |* 474 |* Description All descriptors have to be adapted whose Follow 475 |* refers to the one that has to be deleted. 476 |* 477 |* Created MA 25. Jan. 93 478 |* Last change JP 04.09.95 479 |* 480 |*************************************************************************/ 481 482 // #i7983# 483 void SwDoc::PreDelPageDesc(SwPageDesc * pDel) 484 { 485 if (0 == pDel) 486 return; 487 488 // mba: test iteration as clients are removed while iteration 489 SwPageDescHint aHint( aPageDescs[0] ); 490 pDel->CallSwClientNotify( aHint ); 491 492 bool bHasLayout = HasLayout(); 493 if ( pFtnInfo->DependsOn( pDel ) ) 494 { 495 pFtnInfo->ChgPageDesc( aPageDescs[0] ); 496 if ( bHasLayout ) 497 { 498 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 499 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), false)); 500 } 501 } 502 else if ( pEndNoteInfo->DependsOn( pDel ) ) 503 { 504 pEndNoteInfo->ChgPageDesc( aPageDescs[0] ); 505 if ( bHasLayout ) 506 { 507 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 508 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), true)); 509 } 510 } 511 512 for ( sal_uInt16 j = 0; j < aPageDescs.Count(); ++j ) 513 { 514 if ( aPageDescs[j]->GetFollow() == pDel ) 515 { 516 aPageDescs[j]->SetFollow( 0 ); 517 if( bHasLayout ) 518 { 519 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 520 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080228 521 } 522 } 523 } 524 } 525 526 // #116530# 527 void SwDoc::BroadcastStyleOperation(String rName, SfxStyleFamily eFamily, 528 sal_uInt16 nOp) 529 { 530 if (pDocShell) 531 { 532 SfxStyleSheetBasePool * pPool = pDocShell->GetStyleSheetPool(); 533 534 if (pPool) 535 { 536 pPool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL ); 537 SfxStyleSheetBase * pBase = pPool->Find(rName); 538 539 if (pBase != NULL) 540 pPool->Broadcast(SfxStyleSheetHint( nOp, *pBase )); 541 } 542 } 543 } 544 545 void SwDoc::DelPageDesc( sal_uInt16 i, sal_Bool bBroadcast ) 546 { 547 ASSERT( i < aPageDescs.Count(), "PageDescs are over-indexed." ); 548 ASSERT( i != 0, "Default Pagedesc cannot be deleted." ); 549 if ( i == 0 ) 550 return; 551 552 SwPageDesc *pDel = aPageDescs[i]; 553 554 // -> #116530# 555 if (bBroadcast) 556 BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_PAGE, 557 SFX_STYLESHEET_ERASED); 558 // <- #116530# 559 560 if (GetIDocumentUndoRedo().DoesUndo()) 561 { 562 SwUndo *const pUndo(new SwUndoPageDescDelete(*pDel, this)); 563 GetIDocumentUndoRedo().AppendUndo(pUndo); 564 } 565 566 PreDelPageDesc(pDel); // #i7983# 567 568 aPageDescs.Remove( i ); 569 delete pDel; 570 SetModified(); 571 } 572 573 574 575 /************************************************************************* 576 |* 577 |* SwDoc::MakePageDesc() 578 |* 579 |* Created MA 25. Jan. 93 580 |* Last change MA 20. Aug. 93 581 |* 582 |*************************************************************************/ 583 584 sal_uInt16 SwDoc::MakePageDesc( const String &rName, const SwPageDesc *pCpy, 585 sal_Bool bRegardLanguage, sal_Bool bBroadcast) // #116530# 586 { 587 SwPageDesc *pNew; 588 if( pCpy ) 589 { 590 pNew = new SwPageDesc( *pCpy ); 591 pNew->SetName( rName ); 592 if( rName != pCpy->GetName() ) 593 { 594 pNew->SetPoolFmtId( USHRT_MAX ); 595 pNew->SetPoolHelpId( USHRT_MAX ); 596 pNew->SetPoolHlpFileId( UCHAR_MAX ); 597 } 598 } 599 else 600 { 601 pNew = new SwPageDesc( rName, GetDfltFrmFmt(), this ); 602 // set default page format 603 lcl_DefaultPageFmt( USHRT_MAX, pNew->GetMaster(), pNew->GetLeft() ); 604 605 SvxFrameDirection aFrameDirection = bRegardLanguage ? 606 GetDefaultFrameDirection(GetAppLanguage()) 607 : FRMDIR_HORI_LEFT_TOP; 608 609 pNew->GetMaster().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) ); 610 pNew->GetLeft().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) ); 611 } 612 aPageDescs.Insert( pNew, aPageDescs.Count() ); 613 614 // -> #116530# 615 if (bBroadcast) 616 BroadcastStyleOperation(rName, SFX_STYLE_FAMILY_PAGE, 617 SFX_STYLESHEET_CREATED); 618 // <- #116530# 619 620 if (GetIDocumentUndoRedo().DoesUndo()) 621 { 622 // #116530# 623 GetIDocumentUndoRedo().AppendUndo(new SwUndoPageDescCreate(pNew, this)); 624 } 625 626 SetModified(); 627 return (aPageDescs.Count()-1); 628 } 629 630 SwPageDesc* SwDoc::FindPageDescByName( const String& rName, sal_uInt16* pPos ) const 631 { 632 SwPageDesc* pRet = 0; 633 if( pPos ) *pPos = USHRT_MAX; 634 635 for( sal_uInt16 n = 0, nEnd = aPageDescs.Count(); n < nEnd; ++n ) 636 if( aPageDescs[ n ]->GetName() == rName ) 637 { 638 pRet = aPageDescs[ n ]; 639 if( pPos ) 640 *pPos = n; 641 break; 642 } 643 return pRet; 644 } 645 646 /****************************************************************************** 647 * Method void SwDoc::PrtDataChanged() 648 * Description 649 * Created OK 27.10.94 10:20 650 * Last change MA 26. Mar. 98 651 ******************************************************************************/ 652 653 void SwDoc::PrtDataChanged() 654 { 655 //!!!!!!!! In case of changes please look after InJobSetup in Sw3io if necessary 656 657 // --> FME 2005-01-21 #i41075# 658 ASSERT( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) || 659 0 != getPrinter( sal_False ), "PrtDataChanged will be called recursive!" ) 660 // <-- 661 SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219 662 SwWait *pWait = 0; 663 sal_Bool bEndAction = sal_False; 664 665 if( GetDocShell() ) 666 GetDocShell()->UpdateFontList(); 667 668 sal_Bool bDraw = sal_True; 669 if ( pTmpRoot ) 670 { 671 ViewShell *pSh = GetCurrentViewShell(); 672 if( !pSh->GetViewOptions()->getBrowseMode() || 673 pSh->GetViewOptions()->IsPrtFormat() ) 674 { 675 if ( GetDocShell() ) 676 pWait = new SwWait( *GetDocShell(), true ); 677 678 pTmpRoot->StartAllAction(); 679 bEndAction = sal_True; 680 681 bDraw = sal_False; 682 if( pDrawModel ) 683 { 684 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) ); 685 pDrawModel->SetRefDevice( getReferenceDevice( false ) ); 686 } 687 688 pFntCache->Flush(); 689 690 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 691 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE));//swmod 080304 692 693 if ( pSh ) 694 { 695 do 696 { 697 pSh->InitPrt( pPrt ); 698 pSh = (ViewShell*)pSh->GetNext(); 699 } 700 while ( pSh != GetCurrentViewShell() ); 701 } 702 703 } 704 } //swmod 080218 705 if ( bDraw && pDrawModel ) 706 { 707 const sal_Bool bTmpAddExtLeading = get(IDocumentSettingAccess::ADD_EXT_LEADING); 708 if ( bTmpAddExtLeading != pDrawModel->IsAddExtLeading() ) 709 pDrawModel->SetAddExtLeading( bTmpAddExtLeading ); 710 711 OutputDevice* pOutDev = getReferenceDevice( false ); 712 if ( pOutDev != pDrawModel->GetRefDevice() ) 713 pDrawModel->SetRefDevice( pOutDev ); 714 } 715 716 PrtOLENotify( sal_True ); 717 718 if ( bEndAction ) 719 pTmpRoot->EndAllAction(); //swmod 080218 720 delete pWait; 721 } 722 723 // At run time collect the GlobalNames of the server that don't want 724 // to be notified when printer have changed. 725 // Due to this many objects don't need to be loaded (luckily on top of 726 // this all alien objects are mapped to a single ID). Init and DeInit 727 // of the array can be found in init.cxx. 728 extern SvPtrarr *pGlobalOLEExcludeList; 729 730 void SwDoc::PrtOLENotify( sal_Bool bAll ) 731 { 732 SwFEShell *pShell = 0; 733 if ( GetCurrentViewShell() ) 734 { 735 ViewShell *pSh = GetCurrentViewShell(); 736 if ( !pSh->ISA(SwFEShell) ) 737 do 738 { pSh = (ViewShell*)pSh->GetNext(); 739 } while ( !pSh->ISA(SwFEShell) && 740 pSh != GetCurrentViewShell() ); 741 742 if ( pSh->ISA(SwFEShell) ) 743 pShell = (SwFEShell*)pSh; 744 } //swmod 071107//swmod 071225 745 if ( !pShell ) 746 { 747 // This doesn't make sense without Shell and therefore without Client because 748 // communication relating to change in size is implemented only in this way. 749 // As there is no Shell, note this unfavorable status in the Document, this 750 // will be caught up when creating the first Shell. 751 mbOLEPrtNotifyPending = sal_True; 752 if ( bAll ) 753 mbAllOLENotify = sal_True; 754 } 755 else 756 { 757 if ( mbAllOLENotify ) 758 bAll = sal_True; 759 760 mbOLEPrtNotifyPending = mbAllOLENotify = sal_False; 761 762 SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), !bAll ); 763 if ( pNodes ) 764 { 765 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY, 766 0, pNodes->Count(), GetDocShell()); 767 GetCurrentLayout()->StartAllAction(); //swmod 080218 768 769 for( sal_uInt16 i = 0; i < pNodes->Count(); ++i ) 770 { 771 ::SetProgressState( i, GetDocShell() ); 772 773 SwOLENode* pOLENd = (*pNodes)[i]; 774 pOLENd->SetOLESizeInvalid( sal_False ); 775 776 // first load the information and determine whether it is already in the exclude list 777 SvGlobalName aName; 778 779 svt::EmbeddedObjectRef& xObj = pOLENd->GetOLEObj().GetObject(); 780 if ( xObj.is() ) 781 aName = SvGlobalName( xObj->getClassID() ); 782 else // not yet loaded 783 { 784 // TODO/LATER: retrieve ClassID of an unloaded object 785 // aName = ???? 786 } 787 788 sal_Bool bFound = sal_False; 789 for ( sal_uInt16 j = 0; 790 j < pGlobalOLEExcludeList->Count() && !bFound; 791 ++j ) 792 { 793 bFound = *(SvGlobalName*)(*pGlobalOLEExcludeList)[j] == 794 aName; 795 } 796 if ( bFound ) 797 continue; 798 799 // not known, therefore the object has to be loaded 800 // when notification is not requested 801 if ( xObj.is() ) 802 { 803 //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange 804 /* 805 if ( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xRef->GetMiscStatus()) 806 { 807 if ( pOLENd->GetFrm() ) 808 { 809 xObj->OnDocumentPrinterChanged( pPrt ); 810 pShell->CalcAndSetScale( xObj );// create client 811 } 812 else 813 pOLENd->SetOLESizeInvalid( sal_True ); 814 } 815 else */ 816 pGlobalOLEExcludeList->Insert( 817 new SvGlobalName( aName ), 818 pGlobalOLEExcludeList->Count() ); 819 } 820 } 821 delete pNodes; 822 GetCurrentLayout()->EndAllAction(); //swmod 080218 823 ::EndProgress( GetDocShell() ); 824 } 825 } 826 } 827 828 IMPL_LINK( SwDoc, DoUpdateModifiedOLE, Timer *, ) 829 { 830 SwFEShell* pSh = (SwFEShell*)GetEditShell(); 831 if( pSh ) 832 { 833 mbOLEPrtNotifyPending = mbAllOLENotify = sal_False; 834 835 SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), true ); 836 if( pNodes ) 837 { 838 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY, 839 0, pNodes->Count(), GetDocShell()); 840 GetCurrentLayout()->StartAllAction(); //swmod 080218 841 SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR ); 842 843 for( sal_uInt16 i = 0; i < pNodes->Count(); ++i ) 844 { 845 ::SetProgressState( i, GetDocShell() ); 846 847 SwOLENode* pOLENd = (*pNodes)[i]; 848 pOLENd->SetOLESizeInvalid( sal_False ); 849 850 // not known, therefore the object has to be loaded 851 // when notification is not requested 852 if( pOLENd->GetOLEObj().GetOleRef().is() ) // broken? 853 { 854 //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange 855 /* 856 if( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & 857 xRef->GetMiscStatus() ) 858 { 859 if( pOLENd->GetFrm() ) 860 { 861 xRef->OnDocumentPrinterChanged( pPrt ); 862 pSh->CalcAndSetScale( xRef );// create client 863 } 864 else 865 pOLENd->SetOLESizeInvalid( sal_True ); 866 }*/ 867 // repaint it 868 pOLENd->ModifyNotification( &aMsgHint, &aMsgHint ); 869 } 870 } 871 GetCurrentLayout()->EndAllAction(); //swmod 080218 872 ::EndProgress( GetDocShell() ); 873 delete pNodes; 874 } 875 } 876 return 0; 877 } 878 879 sal_Bool SwDoc::FindPageDesc( const String & rName, sal_uInt16 * pFound) 880 { 881 sal_Bool bResult = sal_False; 882 sal_uInt16 nI; 883 for (nI = 0; nI < aPageDescs.Count(); nI++) 884 { 885 if (aPageDescs[nI]->GetName() == rName) 886 { 887 *pFound = nI; 888 bResult = sal_True; 889 break; 890 } 891 } 892 893 return bResult; 894 } 895 896 SwPageDesc * SwDoc::GetPageDesc( const String & rName ) 897 { 898 SwPageDesc * aResult = NULL; 899 900 sal_uInt16 nI; 901 902 if (FindPageDesc(rName, &nI)) 903 aResult = aPageDescs[nI]; 904 905 return aResult; 906 } 907 908 void SwDoc::DelPageDesc( const String & rName, sal_Bool bBroadcast ) // #116530# 909 { 910 sal_uInt16 nI; 911 912 if (FindPageDesc(rName, &nI)) 913 DelPageDesc(nI, bBroadcast); // #116530# 914 } 915 916 void SwDoc::ChgPageDesc( const String & rName, const SwPageDesc & rDesc) 917 { 918 sal_uInt16 nI; 919 920 if (FindPageDesc(rName, &nI)) 921 ChgPageDesc(nI, rDesc); 922 } 923 924 /* 925 * The HTML import cannot resist changing the page descriptions, I don't 926 * know why. This function is meant to check the page descriptors for invalid 927 * values. 928 */ 929 void SwDoc::CheckDefaultPageFmt() 930 { 931 for ( sal_uInt16 i = 0; i < GetPageDescCnt(); ++i ) 932 { 933 SwPageDesc& rDesc = _GetPageDesc( i ); 934 935 SwFrmFmt& rMaster = rDesc.GetMaster(); 936 SwFrmFmt& rLeft = rDesc.GetLeft(); 937 938 const SwFmtFrmSize& rMasterSize = rMaster.GetFrmSize(); 939 const SwFmtFrmSize& rLeftSize = rLeft.GetFrmSize(); 940 941 const bool bSetSize = LONG_MAX == rMasterSize.GetWidth() || 942 LONG_MAX == rMasterSize.GetHeight() || 943 LONG_MAX == rLeftSize.GetWidth() || 944 LONG_MAX == rLeftSize.GetHeight(); 945 946 if ( bSetSize ) 947 lcl_DefaultPageFmt( rDesc.GetPoolFmtId(), rDesc.GetMaster(), rDesc.GetLeft() ); 948 } 949 } 950 951 void SwDoc::SetDefaultPageMode(bool bSquaredPageMode) 952 { 953 if( !bSquaredPageMode == !IsSquaredPageMode() ) 954 return; 955 956 const SwTextGridItem& rGrid = 957 (const SwTextGridItem&)GetDefault( RES_TEXTGRID ); 958 SwTextGridItem aNewGrid = rGrid; 959 aNewGrid.SetSquaredMode(bSquaredPageMode); 960 aNewGrid.Init(); 961 SetDefault(aNewGrid); 962 963 for ( sal_uInt16 i = 0; i < GetPageDescCnt(); ++i ) 964 { 965 SwPageDesc& rDesc = _GetPageDesc( i ); 966 967 SwFrmFmt& rMaster = rDesc.GetMaster(); 968 SwFrmFmt& rLeft = rDesc.GetLeft(); 969 970 SwTextGridItem aGrid((SwTextGridItem&)rMaster.GetFmtAttr(RES_TEXTGRID)); 971 aGrid.SwitchPaperMode( bSquaredPageMode ); 972 rMaster.SetFmtAttr(aGrid); 973 rLeft.SetFmtAttr(aGrid); 974 } 975 } 976 977 sal_Bool SwDoc::IsSquaredPageMode() const 978 { 979 const SwTextGridItem& rGrid = 980 (const SwTextGridItem&)GetDefault( RES_TEXTGRID ); 981 return rGrid.IsSquaredMode(); 982 } 983 984 /* vim: set noet sw=4 ts=4: */ 985