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 <hintids.hxx> 28 #include <vcl/virdev.hxx> 29 #include <svx/svdmodel.hxx> 30 #include <editeng/ulspitem.hxx> 31 #include <editeng/lrspitem.hxx> 32 #include <editeng/paperinf.hxx> 33 #include "editeng/frmdiritem.hxx" 34 #include <tools/urlobj.hxx> 35 #include <sfx2/docfile.hxx> 36 #include <sfx2/printer.hxx> 37 #include <unotools/localedatawrapper.hxx> 38 #include <com/sun/star/document/PrinterIndependentLayout.hpp> 39 #include <fmtfsize.hxx> 40 #include <fmthdft.hxx> 41 #include <fmtcntnt.hxx> 42 #include <fmtpdsc.hxx> 43 #include <ftninfo.hxx> 44 #include <fesh.hxx> 45 #include <ndole.hxx> 46 #include <mdiexp.hxx> 47 #include <doc.hxx> 48 #include <IDocumentUndoRedo.hxx> 49 #include <docary.hxx> 50 #include <pagefrm.hxx> //Fuer DelPageDesc 51 #include <rootfrm.hxx> //Fuer DelPageDesc 52 #include <ndtxt.hxx> 53 #include <frmtool.hxx> 54 #include <pagedesc.hxx> 55 #include <poolfmt.hxx> 56 #include <docsh.hxx> 57 #include <ndindex.hxx> 58 #include <ftnidx.hxx> 59 #include <fmtftn.hxx> 60 #include <txtftn.hxx> 61 #include <fntcache.hxx> 62 #include <viewsh.hxx> 63 #include <viewopt.hxx> 64 #include <fldbas.hxx> 65 #include <swwait.hxx> 66 #include <GetMetricVal.hxx> 67 #include <unotools/syslocale.hxx> 68 #include <statstr.hrc> 69 #include <switerator.hxx> 70 #include <hints.hxx> 71 #include <SwUndoPageDesc.hxx> 72 #include <pagedeschint.hxx> 73 #include <tgrditem.hxx> 74 75 using namespace com::sun::star; 76 77 static void lcl_DefaultPageFmt( sal_uInt16 nPoolFmtId, 78 SwFrmFmt &rFmt1, 79 SwFrmFmt &rFmt2 ) 80 { 81 // --> FME 2005-01-21 #i41075# Printer on demand 82 // This function does not require a printer anymore. 83 // The default page size is obtained from the application 84 //locale 85 // <-- 86 87 SwFmtFrmSize aFrmSize( ATT_FIX_SIZE ); 88 const Size aPhysSize = SvxPaperInfo::GetDefaultPaperSize(); 89 aFrmSize.SetSize( aPhysSize ); 90 91 //Auf Default-Raender vorbereiten. 92 //Raender haben eine defaultmaessige Mindestgroesse. 93 //wenn der Drucker einen groesseren Rand vorgibt, so 94 //ist mir dass auch recht. 95 // MIB 06/25/2002, #99397#: The HTML page desc had A4 as page size 96 // always. This has been changed to take the page size from the printer. 97 // Unfortunately, the margins of the HTML page desc are smaller than 98 // the margins used here in general, so one extra case is required. 99 // In the long term, this needs to be changed to always keep the 100 // margins from the page desc. 101 sal_Int32 nMinTop, nMinBottom, nMinLeft, nMinRight; 102 if( RES_POOLPAGE_HTML == nPoolFmtId ) 103 { 104 nMinRight = nMinTop = nMinBottom = GetMetricVal( CM_1 ); 105 nMinLeft = nMinRight * 2; 106 } 107 else if( MEASURE_METRIC == SvtSysLocale().GetLocaleData().getMeasurementSystemEnum() ) 108 { 109 nMinTop = nMinBottom = nMinLeft = nMinRight = 1134; //2 Zentimeter 110 } 111 else 112 { 113 nMinTop = nMinBottom = 1440; //al la WW: 1Inch 114 nMinLeft = nMinRight = 1800; // 1,25 Inch 115 } 116 117 //Raender einstellen. 118 SvxLRSpaceItem aLR( RES_LR_SPACE ); 119 SvxULSpaceItem aUL( RES_UL_SPACE ); 120 121 aUL.SetUpper( (sal_uInt16)nMinTop ); 122 aUL.SetLower( (sal_uInt16)nMinBottom ); 123 aLR.SetRight( nMinRight ); 124 aLR.SetLeft( nMinLeft ); 125 126 rFmt1.SetFmtAttr( aFrmSize ); 127 rFmt1.SetFmtAttr( aLR ); 128 rFmt1.SetFmtAttr( aUL ); 129 130 rFmt2.SetFmtAttr( aFrmSize ); 131 rFmt2.SetFmtAttr( aLR ); 132 rFmt2.SetFmtAttr( aUL ); 133 } 134 135 /************************************************************************* 136 |* 137 |* SwDoc::ChgPageDesc() 138 |* 139 |* Ersterstellung MA 25. Jan. 93 140 |* Letzte Aenderung MA 01. Mar. 95 141 |* 142 |*************************************************************************/ 143 144 void lcl_DescSetAttr( const SwFrmFmt &rSource, SwFrmFmt &rDest, 145 const sal_Bool bPage = sal_True ) 146 { 147 /////////////// !!!!!!!!!!!!!!!! 148 //JP 03.03.99: 149 // eigentlich sollte hier das Intersect von ItemSet benutzt werden, aber das 150 // funktioniert nicht richtig, wenn man unterschiedliche WhichRanges hat. 151 /////////////// !!!!!!!!!!!!!!!! 152 //Die interressanten Attribute uebernehmen. 153 sal_uInt16 __READONLY_DATA aIdArr[] = { RES_FRM_SIZE, RES_UL_SPACE, 154 RES_BACKGROUND, RES_SHADOW, 155 RES_COL, RES_COL, 156 RES_FRAMEDIR, RES_FRAMEDIR, 157 RES_TEXTGRID, RES_TEXTGRID, 158 // --> FME 2005-04-18 #i45539# 159 RES_HEADER_FOOTER_EAT_SPACING, 160 RES_HEADER_FOOTER_EAT_SPACING, 161 // <-- 162 RES_UNKNOWNATR_CONTAINER, 163 RES_UNKNOWNATR_CONTAINER, 164 0 }; 165 166 const SfxPoolItem* pItem; 167 for( sal_uInt16 n = 0; aIdArr[ n ]; n += 2 ) 168 { 169 for( sal_uInt16 nId = aIdArr[ n ]; nId <= aIdArr[ n+1]; ++nId ) 170 { 171 // --> FME 2005-04-18 #i45539# 172 // bPage == true: 173 // All in aIdArr except from RES_HEADER_FOOTER_EAT_SPACING 174 // bPage == false: 175 // All in aIdArr except from RES_COL and RES_PAPER_BIN: 176 // <-- 177 if( ( bPage && RES_HEADER_FOOTER_EAT_SPACING != nId ) || 178 ( !bPage && RES_COL != nId && RES_PAPER_BIN != nId )) 179 { 180 if( SFX_ITEM_SET == rSource.GetItemState( nId, sal_False, &pItem )) 181 rDest.SetFmtAttr( *pItem ); 182 else 183 rDest.ResetFmtAttr( nId ); 184 } 185 } 186 } 187 188 // auch Pool-, Hilfe-Id's uebertragen 189 rDest.SetPoolFmtId( rSource.GetPoolFmtId() ); 190 rDest.SetPoolHelpId( rSource.GetPoolHelpId() ); 191 rDest.SetPoolHlpFileId( rSource.GetPoolHlpFileId() ); 192 } 193 194 195 void SwDoc::ChgPageDesc( sal_uInt16 i, const SwPageDesc &rChged ) 196 { 197 ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." ); 198 199 SwPageDesc *pDesc = aPageDescs[i]; 200 SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219 201 202 if (GetIDocumentUndoRedo().DoesUndo()) 203 { 204 SwUndo *const pUndo(new SwUndoPageDesc(*pDesc, rChged, this)); 205 GetIDocumentUndoRedo().AppendUndo(pUndo); 206 } 207 ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo()); 208 209 //Als erstes wird ggf. gespiegelt. 210 if ( rChged.GetUseOn() == nsUseOnPage::PD_MIRROR ) 211 ((SwPageDesc&)rChged).Mirror(); 212 else 213 //sonst Werte aus Master nach Left uebertragen. 214 ::lcl_DescSetAttr( ((SwPageDesc&)rChged).GetMaster(), 215 ((SwPageDesc&)rChged).GetLeft() ); 216 217 //NumType uebernehmen. 218 if( rChged.GetNumType().GetNumberingType() != pDesc->GetNumType().GetNumberingType() ) 219 { 220 pDesc->SetNumType( rChged.GetNumType() ); 221 // JP 30.03.99: Bug 64121 - den Seitennummernfeldern bescheid sagen, 222 // das sich das Num-Format geaendert hat 223 GetSysFldType( RES_PAGENUMBERFLD )->UpdateFlds(); 224 GetSysFldType( RES_REFPAGEGETFLD )->UpdateFlds(); 225 226 // Wenn sich die Numerierungsart geaendert hat, koennte es QuoVadis/ 227 // ErgoSum-Texte geben, die sich auf eine geaenderte Seite beziehen, 228 // deshalb werden die Fussnoten invalidiert 229 SwFtnIdxs& rFtnIdxs = GetFtnIdxs(); 230 for( sal_uInt16 nPos = 0; nPos < rFtnIdxs.Count(); ++nPos ) 231 { 232 SwTxtFtn *pTxtFtn = rFtnIdxs[ nPos ]; 233 const SwFmtFtn &rFtn = pTxtFtn->GetFtn(); 234 pTxtFtn->SetNumber( rFtn.GetNumber(), &rFtn.GetNumStr()); 235 } 236 } 237 238 //Orientierung uebernehmen 239 pDesc->SetLandscape( rChged.GetLandscape() ); 240 241 // #i46909# no undo if header or footer changed 242 bool bHeaderFooterChanged = false; 243 244 //Header abgleichen. 245 const SwFmtHeader &rHead = rChged.GetMaster().GetHeader(); 246 if (undoGuard.UndoWasEnabled()) 247 { 248 // #i46909# no undo if header or footer changed 249 // hat sich an den Nodes etwas veraendert ? 250 const SwFmtHeader &rOldHead = pDesc->GetMaster().GetHeader(); 251 bHeaderFooterChanged |= 252 ( rHead.IsActive() != rOldHead.IsActive() || 253 rChged.IsHeaderShared() != pDesc->IsHeaderShared() ); 254 } 255 pDesc->GetMaster().SetFmtAttr( rHead ); 256 if ( rChged.IsHeaderShared() || !rHead.IsActive() ) 257 { 258 //Left teilt sich den Header mit dem Master. 259 pDesc->GetLeft().SetFmtAttr( pDesc->GetMaster().GetHeader() ); 260 } 261 else if ( rHead.IsActive() ) 262 { //Left bekommt einen eigenen Header verpasst wenn das Format nicht 263 //bereits einen hat. 264 //Wenn er bereits einen hat und dieser auf die gleiche Section 265 //wie der Rechte zeigt, so muss er einen eigenen bekommen. Der 266 //Inhalt wird sinnigerweise kopiert. 267 const SwFmtHeader &rLeftHead = pDesc->GetLeft().GetHeader(); 268 if ( !rLeftHead.IsActive() ) 269 { 270 SwFmtHeader aHead( MakeLayoutFmt( RND_STD_HEADERL, 0 ) ); 271 pDesc->GetLeft().SetFmtAttr( aHead ); 272 //Weitere Attribute (Raender, Umrandung...) uebernehmen. 273 ::lcl_DescSetAttr( *rHead.GetHeaderFmt(), *aHead.GetHeaderFmt(), sal_False); 274 } 275 else 276 { 277 const SwFrmFmt *pRight = rHead.GetHeaderFmt(); 278 const SwFmtCntnt &aRCnt = pRight->GetCntnt(); 279 const SwFmtCntnt &aLCnt = rLeftHead.GetHeaderFmt()->GetCntnt(); 280 if( !aLCnt.GetCntntIdx() ) 281 pDesc->GetLeft().SetFmtAttr( rChged.GetLeft().GetHeader() ); 282 else if( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) ) 283 { 284 SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Header", 285 GetDfltFrmFmt() ); 286 ::lcl_DescSetAttr( *pRight, *pFmt, sal_False ); 287 //Der Bereich auf den das rechte Kopfattribut zeigt wird 288 //kopiert und der Index auf den StartNode in das linke 289 //Kopfattribut gehaengt. 290 SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() ); 291 SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwHeaderStartNode ); 292 SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0, 293 *aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() ); 294 aTmp = *pSttNd->EndOfSectionNode(); 295 GetNodes()._Copy( aRange, aTmp, sal_False ); 296 297 pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ) ); 298 pDesc->GetLeft().SetFmtAttr( SwFmtHeader( pFmt ) ); 299 } 300 else 301 ::lcl_DescSetAttr( *pRight, 302 *(SwFrmFmt*)rLeftHead.GetHeaderFmt(), sal_False ); 303 304 } 305 } 306 pDesc->ChgHeaderShare( rChged.IsHeaderShared() ); 307 308 //Footer abgleichen. 309 const SwFmtFooter &rFoot = rChged.GetMaster().GetFooter(); 310 if (undoGuard.UndoWasEnabled()) 311 { 312 // #i46909# no undo if header or footer changed 313 // hat sich an den Nodes etwas veraendert ? 314 const SwFmtFooter &rOldFoot = pDesc->GetMaster().GetFooter(); 315 bHeaderFooterChanged |= 316 ( rFoot.IsActive() != rOldFoot.IsActive() || 317 rChged.IsFooterShared() != pDesc->IsFooterShared() ); 318 } 319 pDesc->GetMaster().SetFmtAttr( rFoot ); 320 if ( rChged.IsFooterShared() || !rFoot.IsActive() ) 321 //Left teilt sich den Header mit dem Master. 322 pDesc->GetLeft().SetFmtAttr( pDesc->GetMaster().GetFooter() ); 323 else if ( rFoot.IsActive() ) 324 { //Left bekommt einen eigenen Footer verpasst wenn das Format nicht 325 //bereits einen hat. 326 //Wenn er bereits einen hat und dieser auf die gleiche Section 327 //wie der Rechte zeigt, so muss er einen eigenen bekommen. Der 328 //Inhalt wird sinnigerweise kopiert. 329 const SwFmtFooter &rLeftFoot = pDesc->GetLeft().GetFooter(); 330 if ( !rLeftFoot.IsActive() ) 331 { 332 SwFmtFooter aFoot( MakeLayoutFmt( RND_STD_FOOTER, 0 ) ); 333 pDesc->GetLeft().SetFmtAttr( aFoot ); 334 //Weitere Attribute (Raender, Umrandung...) uebernehmen. 335 ::lcl_DescSetAttr( *rFoot.GetFooterFmt(), *aFoot.GetFooterFmt(), sal_False); 336 } 337 else 338 { 339 const SwFrmFmt *pRight = rFoot.GetFooterFmt(); 340 const SwFmtCntnt &aRCnt = pRight->GetCntnt(); 341 const SwFmtCntnt &aLCnt = rLeftFoot.GetFooterFmt()->GetCntnt(); 342 if( !aLCnt.GetCntntIdx() ) 343 pDesc->GetLeft().SetFmtAttr( rChged.GetLeft().GetFooter() ); 344 else if( (*aRCnt.GetCntntIdx()) == (*aLCnt.GetCntntIdx()) ) 345 { 346 SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), "Footer", 347 GetDfltFrmFmt() ); 348 ::lcl_DescSetAttr( *pRight, *pFmt, sal_False ); 349 //Der Bereich auf den das rechte Kopfattribut zeigt wird 350 //kopiert und der Index auf den StartNode in das linke 351 //Kopfattribut gehaengt. 352 SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() ); 353 SwStartNode* pSttNd = GetNodes().MakeEmptySection( aTmp, SwFooterStartNode ); 354 SwNodeRange aRange( aRCnt.GetCntntIdx()->GetNode(), 0, 355 *aRCnt.GetCntntIdx()->GetNode().EndOfSectionNode() ); 356 aTmp = *pSttNd->EndOfSectionNode(); 357 GetNodes()._Copy( aRange, aTmp, sal_False ); 358 359 pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ) ); 360 pDesc->GetLeft().SetFmtAttr( SwFmtFooter( pFmt ) ); 361 } 362 else 363 ::lcl_DescSetAttr( *pRight, 364 *(SwFrmFmt*)rLeftFoot.GetFooterFmt(), sal_False ); 365 } 366 } 367 pDesc->ChgFooterShare( rChged.IsFooterShared() ); 368 369 if ( pDesc->GetName() != rChged.GetName() ) 370 pDesc->SetName( rChged.GetName() ); 371 372 // Dadurch wird ein RegisterChange ausgeloest, wenn notwendig 373 pDesc->SetRegisterFmtColl( rChged.GetRegisterFmtColl() ); 374 375 //Wenn sich das UseOn oder der Follow aendern muessen die 376 //Absaetze das erfahren. 377 sal_Bool bUseOn = sal_False; 378 sal_Bool bFollow = sal_False; 379 if ( pDesc->GetUseOn() != rChged.GetUseOn() ) 380 { pDesc->SetUseOn( rChged.GetUseOn() ); 381 bUseOn = sal_True; 382 } 383 if ( pDesc->GetFollow() != rChged.GetFollow() ) 384 { if ( rChged.GetFollow() == &rChged ) 385 { if ( pDesc->GetFollow() != pDesc ) 386 { pDesc->SetFollow( pDesc ); 387 bFollow = sal_True; 388 } 389 } 390 else 391 { pDesc->SetFollow( rChged.pFollow ); 392 bFollow = sal_True; 393 } 394 } 395 396 if ( (bUseOn || bFollow) && pTmpRoot) 397 //Layot benachrichtigen! 398 { 399 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 400 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080304 401 } 402 403 //Jetzt noch die Seiten-Attribute uebernehmen. 404 ::lcl_DescSetAttr( rChged.GetMaster(), pDesc->GetMaster() ); 405 ::lcl_DescSetAttr( rChged.GetLeft(), pDesc->GetLeft() ); 406 407 //Wenn sich FussnotenInfo veraendert, so werden die Seiten 408 //angetriggert. 409 if( !(pDesc->GetFtnInfo() == rChged.GetFtnInfo()) ) 410 { 411 pDesc->SetFtnInfo( rChged.GetFtnInfo() ); 412 SwMsgPoolItem aInfo( RES_PAGEDESC_FTNINFO ); 413 { 414 pDesc->GetMaster().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) ); 415 } 416 { 417 pDesc->GetLeft().ModifyBroadcast( &aInfo, 0, TYPE(SwFrm) ); 418 } 419 } 420 SetModified(); 421 422 // #i46909# no undo if header or footer changed 423 if( bHeaderFooterChanged ) 424 { 425 GetIDocumentUndoRedo().DelAllUndoObj(); 426 } 427 } 428 429 /************************************************************************* 430 |* 431 |* SwDoc::DelPageDesc() 432 |* 433 |* Beschreibung Alle Descriptoren, deren Follow auf den zu loeschenden 434 |* zeigen muessen angepasst werden. 435 |* Ersterstellung MA 25. Jan. 93 436 |* Letzte Aenderung JP 04.09.95 437 |* 438 |*************************************************************************/ 439 440 // #i7983# 441 void SwDoc::PreDelPageDesc(SwPageDesc * pDel) 442 { 443 if (0 == pDel) 444 return; 445 446 // mba: test iteration as clients are removed while iteration 447 SwPageDescHint aHint( aPageDescs[0] ); 448 pDel->CallSwClientNotify( aHint ); 449 450 bool bHasLayout = HasLayout(); 451 if ( pFtnInfo->DependsOn( pDel ) ) 452 { 453 pFtnInfo->ChgPageDesc( aPageDescs[0] ); 454 if ( bHasLayout ) 455 { 456 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 457 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), false)); 458 } 459 } 460 else if ( pEndNoteInfo->DependsOn( pDel ) ) 461 { 462 pEndNoteInfo->ChgPageDesc( aPageDescs[0] ); 463 if ( bHasLayout ) 464 { 465 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 466 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), true)); 467 } 468 } 469 470 for ( sal_uInt16 j = 0; j < aPageDescs.Count(); ++j ) 471 { 472 if ( aPageDescs[j]->GetFollow() == pDel ) 473 { 474 aPageDescs[j]->SetFollow( 0 ); 475 if( bHasLayout ) 476 { 477 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 478 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080228 479 } 480 } 481 } 482 } 483 484 // #116530# 485 void SwDoc::BroadcastStyleOperation(String rName, SfxStyleFamily eFamily, 486 sal_uInt16 nOp) 487 { 488 if (pDocShell) 489 { 490 SfxStyleSheetBasePool * pPool = pDocShell->GetStyleSheetPool(); 491 492 if (pPool) 493 { 494 pPool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL ); 495 SfxStyleSheetBase * pBase = pPool->Find(rName); 496 497 if (pBase != NULL) 498 pPool->Broadcast(SfxStyleSheetHint( nOp, *pBase )); 499 } 500 } 501 } 502 503 void SwDoc::DelPageDesc( sal_uInt16 i, sal_Bool bBroadcast ) 504 { 505 ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." ); 506 ASSERT( i != 0, "Default Pagedesc loeschen is nicht." ); 507 if ( i == 0 ) 508 return; 509 510 SwPageDesc *pDel = aPageDescs[i]; 511 512 // -> #116530# 513 if (bBroadcast) 514 BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_PAGE, 515 SFX_STYLESHEET_ERASED); 516 // <- #116530# 517 518 if (GetIDocumentUndoRedo().DoesUndo()) 519 { 520 SwUndo *const pUndo(new SwUndoPageDescDelete(*pDel, this)); 521 GetIDocumentUndoRedo().AppendUndo(pUndo); 522 } 523 524 PreDelPageDesc(pDel); // #i7983# 525 526 aPageDescs.Remove( i ); 527 delete pDel; 528 SetModified(); 529 } 530 531 532 533 /************************************************************************* 534 |* 535 |* SwDoc::MakePageDesc() 536 |* 537 |* Ersterstellung MA 25. Jan. 93 538 |* Letzte Aenderung MA 20. Aug. 93 539 |* 540 |*************************************************************************/ 541 542 sal_uInt16 SwDoc::MakePageDesc( const String &rName, const SwPageDesc *pCpy, 543 sal_Bool bRegardLanguage, sal_Bool bBroadcast) // #116530# 544 { 545 SwPageDesc *pNew; 546 if( pCpy ) 547 { 548 pNew = new SwPageDesc( *pCpy ); 549 pNew->SetName( rName ); 550 if( rName != pCpy->GetName() ) 551 { 552 pNew->SetPoolFmtId( USHRT_MAX ); 553 pNew->SetPoolHelpId( USHRT_MAX ); 554 pNew->SetPoolHlpFileId( UCHAR_MAX ); 555 } 556 } 557 else 558 { 559 pNew = new SwPageDesc( rName, GetDfltFrmFmt(), this ); 560 //Default-Seitenformat einstellen. 561 lcl_DefaultPageFmt( USHRT_MAX, pNew->GetMaster(), pNew->GetLeft() ); 562 563 SvxFrameDirection aFrameDirection = bRegardLanguage ? 564 GetDefaultFrameDirection(GetAppLanguage()) 565 : FRMDIR_HORI_LEFT_TOP; 566 567 pNew->GetMaster().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) ); 568 pNew->GetLeft().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) ); 569 } 570 aPageDescs.Insert( pNew, aPageDescs.Count() ); 571 572 // -> #116530# 573 if (bBroadcast) 574 BroadcastStyleOperation(rName, SFX_STYLE_FAMILY_PAGE, 575 SFX_STYLESHEET_CREATED); 576 // <- #116530# 577 578 if (GetIDocumentUndoRedo().DoesUndo()) 579 { 580 // #116530# 581 GetIDocumentUndoRedo().AppendUndo(new SwUndoPageDescCreate(pNew, this)); 582 } 583 584 SetModified(); 585 return (aPageDescs.Count()-1); 586 } 587 588 SwPageDesc* SwDoc::FindPageDescByName( const String& rName, sal_uInt16* pPos ) const 589 { 590 SwPageDesc* pRet = 0; 591 if( pPos ) *pPos = USHRT_MAX; 592 593 for( sal_uInt16 n = 0, nEnd = aPageDescs.Count(); n < nEnd; ++n ) 594 if( aPageDescs[ n ]->GetName() == rName ) 595 { 596 pRet = aPageDescs[ n ]; 597 if( pPos ) 598 *pPos = n; 599 break; 600 } 601 return pRet; 602 } 603 604 /****************************************************************************** 605 * Methode : void SwDoc::PrtDataChanged() 606 * Beschreibung: 607 * Erstellt : OK 27.10.94 10:20 608 * Aenderung : MA 26. Mar. 98 609 ******************************************************************************/ 610 611 void SwDoc::PrtDataChanged() 612 { 613 //!!!!!!!! Bei Aenderungen hier bitte ggf. InJobSetup im Sw3io mitpflegen 614 615 // --> FME 2005-01-21 #i41075# 616 ASSERT( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) || 617 0 != getPrinter( sal_False ), "PrtDataChanged will be called recursive!" ) 618 // <-- 619 SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219 620 SwWait *pWait = 0; 621 sal_Bool bEndAction = sal_False; 622 623 if( GetDocShell() ) 624 GetDocShell()->UpdateFontList(); 625 626 sal_Bool bDraw = sal_True; 627 if ( pTmpRoot ) 628 { 629 ViewShell *pSh = GetCurrentViewShell(); 630 if( !pSh->GetViewOptions()->getBrowseMode() || 631 pSh->GetViewOptions()->IsPrtFormat() ) 632 { 633 if ( GetDocShell() ) 634 pWait = new SwWait( *GetDocShell(), sal_True ); 635 636 pTmpRoot->StartAllAction(); 637 bEndAction = sal_True; 638 639 bDraw = sal_False; 640 if( pDrawModel ) 641 { 642 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) ); 643 pDrawModel->SetRefDevice( getReferenceDevice( false ) ); 644 } 645 646 pFntCache->Flush(); 647 648 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 649 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE));//swmod 080304 650 651 if ( pSh ) 652 { 653 do 654 { 655 pSh->InitPrt( pPrt ); 656 pSh = (ViewShell*)pSh->GetNext(); 657 } 658 while ( pSh != GetCurrentViewShell() ); 659 } 660 661 } 662 } //swmod 080218 663 if ( bDraw && pDrawModel ) 664 { 665 const sal_Bool bTmpAddExtLeading = get(IDocumentSettingAccess::ADD_EXT_LEADING); 666 if ( bTmpAddExtLeading != pDrawModel->IsAddExtLeading() ) 667 pDrawModel->SetAddExtLeading( bTmpAddExtLeading ); 668 669 OutputDevice* pOutDev = getReferenceDevice( false ); 670 if ( pOutDev != pDrawModel->GetRefDevice() ) 671 pDrawModel->SetRefDevice( pOutDev ); 672 } 673 674 PrtOLENotify( sal_True ); 675 676 if ( bEndAction ) 677 pTmpRoot->EndAllAction(); //swmod 080218 678 delete pWait; 679 } 680 681 //Zur Laufzeit sammeln wir die GlobalNames der Server, die keine 682 //Benachrichtigung zu Druckerwechseln wuenschen. Dadurch sparen wir 683 //das Laden vieler Objekte (gluecklicherweise werden obendrein alle 684 //Fremdobjekte unter einer ID abgebuildet). Init und DeInit vom Array 685 //ist in init.cxx zu finden. 686 extern SvPtrarr *pGlobalOLEExcludeList; 687 688 void SwDoc::PrtOLENotify( sal_Bool bAll ) 689 { 690 SwFEShell *pShell = 0; 691 if ( GetCurrentViewShell() ) 692 { 693 ViewShell *pSh = GetCurrentViewShell(); 694 if ( !pSh->ISA(SwFEShell) ) 695 do 696 { pSh = (ViewShell*)pSh->GetNext(); 697 } while ( !pSh->ISA(SwFEShell) && 698 pSh != GetCurrentViewShell() ); 699 700 if ( pSh->ISA(SwFEShell) ) 701 pShell = (SwFEShell*)pSh; 702 } //swmod 071107//swmod 071225 703 if ( !pShell ) 704 { 705 //Das hat ohne Shell und damit ohne Client keinen Sinn, weil nur darueber 706 //die Kommunikation bezueglich der Groessenaenderung implementiert ist. 707 //Da wir keine Shell haben, merken wir uns diesen unguenstigen 708 //Zustand am Dokument, dies wird dann beim Erzeugen der ersten Shell 709 //nachgeholt. 710 mbOLEPrtNotifyPending = sal_True; 711 if ( bAll ) 712 mbAllOLENotify = sal_True; 713 } 714 else 715 { 716 if ( mbAllOLENotify ) 717 bAll = sal_True; 718 719 mbOLEPrtNotifyPending = mbAllOLENotify = sal_False; 720 721 SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), !bAll ); 722 if ( pNodes ) 723 { 724 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY, 725 0, pNodes->Count(), GetDocShell()); 726 GetCurrentLayout()->StartAllAction(); //swmod 080218 727 728 for( sal_uInt16 i = 0; i < pNodes->Count(); ++i ) 729 { 730 ::SetProgressState( i, GetDocShell() ); 731 732 SwOLENode* pOLENd = (*pNodes)[i]; 733 pOLENd->SetOLESizeInvalid( sal_False ); 734 735 //Ersteinmal die Infos laden und festellen ob das Teil nicht 736 //schon in der Exclude-Liste steht 737 SvGlobalName aName; 738 739 svt::EmbeddedObjectRef& xObj = pOLENd->GetOLEObj().GetObject(); 740 if ( xObj.is() ) 741 aName = SvGlobalName( xObj->getClassID() ); 742 else //Noch nicht geladen 743 { 744 // TODO/LATER: retrieve ClassID of an unloaded object 745 // aName = ???? 746 } 747 748 sal_Bool bFound = sal_False; 749 for ( sal_uInt16 j = 0; 750 j < pGlobalOLEExcludeList->Count() && !bFound; 751 ++j ) 752 { 753 bFound = *(SvGlobalName*)(*pGlobalOLEExcludeList)[j] == 754 aName; 755 } 756 if ( bFound ) 757 continue; 758 759 //Kennen wir nicht, also muss das Objekt geladen werden. 760 //Wenn es keine Benachrichtigung wuenscht 761 if ( xObj.is() ) 762 { 763 //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange 764 /* 765 if ( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xRef->GetMiscStatus()) 766 { 767 if ( pOLENd->GetFrm() ) 768 { 769 xObj->OnDocumentPrinterChanged( pPrt ); 770 pShell->CalcAndSetScale( xObj );//Client erzeugen lassen. 771 } 772 else 773 pOLENd->SetOLESizeInvalid( sal_True ); 774 } 775 else */ 776 pGlobalOLEExcludeList->Insert( 777 new SvGlobalName( aName ), 778 pGlobalOLEExcludeList->Count() ); 779 } 780 } 781 delete pNodes; 782 GetCurrentLayout()->EndAllAction(); //swmod 080218 783 ::EndProgress( GetDocShell() ); 784 } 785 } 786 } 787 788 IMPL_LINK( SwDoc, DoUpdateModifiedOLE, Timer *, ) 789 { 790 SwFEShell* pSh = (SwFEShell*)GetEditShell(); 791 if( pSh ) 792 { 793 mbOLEPrtNotifyPending = mbAllOLENotify = sal_False; 794 795 SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), true ); 796 if( pNodes ) 797 { 798 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY, 799 0, pNodes->Count(), GetDocShell()); 800 GetCurrentLayout()->StartAllAction(); //swmod 080218 801 SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR ); 802 803 for( sal_uInt16 i = 0; i < pNodes->Count(); ++i ) 804 { 805 ::SetProgressState( i, GetDocShell() ); 806 807 SwOLENode* pOLENd = (*pNodes)[i]; 808 pOLENd->SetOLESizeInvalid( sal_False ); 809 810 //Kennen wir nicht, also muss das Objekt geladen werden. 811 //Wenn es keine Benachrichtigung wuenscht 812 if( pOLENd->GetOLEObj().GetOleRef().is() ) //Kaputt? 813 { 814 //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange 815 /* 816 if( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & 817 xRef->GetMiscStatus() ) 818 { 819 if( pOLENd->GetFrm() ) 820 { 821 xRef->OnDocumentPrinterChanged( pPrt ); 822 pSh->CalcAndSetScale( xRef );//Client erzeugen lassen. 823 } 824 else 825 pOLENd->SetOLESizeInvalid( sal_True ); 826 }*/ 827 // repaint it 828 pOLENd->ModifyNotification( &aMsgHint, &aMsgHint ); 829 } 830 } 831 GetCurrentLayout()->EndAllAction(); //swmod 080218 832 ::EndProgress( GetDocShell() ); 833 delete pNodes; 834 } 835 } 836 return 0; 837 } 838 839 sal_Bool SwDoc::FindPageDesc( const String & rName, sal_uInt16 * pFound) 840 { 841 sal_Bool bResult = sal_False; 842 sal_uInt16 nI; 843 for (nI = 0; nI < aPageDescs.Count(); nI++) 844 { 845 if (aPageDescs[nI]->GetName() == rName) 846 { 847 *pFound = nI; 848 bResult = sal_True; 849 break; 850 } 851 } 852 853 return bResult; 854 } 855 856 SwPageDesc * SwDoc::GetPageDesc( const String & rName ) 857 { 858 SwPageDesc * aResult = NULL; 859 860 sal_uInt16 nI; 861 862 if (FindPageDesc(rName, &nI)) 863 aResult = aPageDescs[nI]; 864 865 return aResult; 866 } 867 868 void SwDoc::DelPageDesc( const String & rName, sal_Bool bBroadcast ) // #116530# 869 { 870 sal_uInt16 nI; 871 872 if (FindPageDesc(rName, &nI)) 873 DelPageDesc(nI, bBroadcast); // #116530# 874 } 875 876 void SwDoc::ChgPageDesc( const String & rName, const SwPageDesc & rDesc) 877 { 878 sal_uInt16 nI; 879 880 if (FindPageDesc(rName, &nI)) 881 ChgPageDesc(nI, rDesc); 882 } 883 884 /* 885 * The HTML import cannot resist changing the page descriptions, I don't 886 * know why. This function is meant to check the page descriptors for invalid 887 * values. 888 */ 889 void SwDoc::CheckDefaultPageFmt() 890 { 891 for ( sal_uInt16 i = 0; i < GetPageDescCnt(); ++i ) 892 { 893 SwPageDesc& rDesc = _GetPageDesc( i ); 894 895 SwFrmFmt& rMaster = rDesc.GetMaster(); 896 SwFrmFmt& rLeft = rDesc.GetLeft(); 897 898 const SwFmtFrmSize& rMasterSize = rMaster.GetFrmSize(); 899 const SwFmtFrmSize& rLeftSize = rLeft.GetFrmSize(); 900 901 const bool bSetSize = LONG_MAX == rMasterSize.GetWidth() || 902 LONG_MAX == rMasterSize.GetHeight() || 903 LONG_MAX == rLeftSize.GetWidth() || 904 LONG_MAX == rLeftSize.GetHeight(); 905 906 if ( bSetSize ) 907 lcl_DefaultPageFmt( rDesc.GetPoolFmtId(), rDesc.GetMaster(), rDesc.GetLeft() ); 908 } 909 } 910 911 void SwDoc::SetDefaultPageMode(bool bSquaredPageMode) 912 { 913 if( !bSquaredPageMode == !IsSquaredPageMode() ) 914 return; 915 916 const SwTextGridItem& rGrid = 917 (const SwTextGridItem&)GetDefault( RES_TEXTGRID ); 918 SwTextGridItem aNewGrid = rGrid; 919 aNewGrid.SetSquaredMode(bSquaredPageMode); 920 aNewGrid.Init(); 921 SetDefault(aNewGrid); 922 923 for ( sal_uInt16 i = 0; i < GetPageDescCnt(); ++i ) 924 { 925 SwPageDesc& rDesc = _GetPageDesc( i ); 926 927 SwFrmFmt& rMaster = rDesc.GetMaster(); 928 SwFrmFmt& rLeft = rDesc.GetLeft(); 929 930 SwTextGridItem aGrid((SwTextGridItem&)rMaster.GetFmtAttr(RES_TEXTGRID)); 931 aGrid.SwitchPaperMode( bSquaredPageMode ); 932 rMaster.SetFmtAttr(aGrid); 933 rLeft.SetFmtAttr(aGrid); 934 } 935 } 936 937 sal_Bool SwDoc::IsSquaredPageMode() const 938 { 939 const SwTextGridItem& rGrid = 940 (const SwTextGridItem&)GetDefault( RES_TEXTGRID ); 941 return rGrid.IsSquaredMode(); 942 } 943