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