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