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 = 432 ( GetDocShell() && GetDocShell()->GetDispatcher() ) ? GetDocShell()->GetDispatcher()->GetBindings() : 0; 433 if ( pBindings ) 434 { 435 pBindings->Invalidate( SID_ATTR_PAGE_COLUMN ); 436 pBindings->Invalidate( SID_ATTR_PAGE ); 437 pBindings->Invalidate( SID_ATTR_PAGE_SIZE ); 438 pBindings->Invalidate( SID_ATTR_PAGE_ULSPACE ); 439 pBindings->Invalidate( SID_ATTR_PAGE_LRSPACE ); 440 } 441 442 } 443 444 /************************************************************************* 445 |* 446 |* SwDoc::DelPageDesc() 447 |* 448 |* Beschreibung Alle Descriptoren, deren Follow auf den zu loeschenden 449 |* zeigen muessen angepasst werden. 450 |* Ersterstellung MA 25. Jan. 93 451 |* Letzte Aenderung JP 04.09.95 452 |* 453 |*************************************************************************/ 454 455 // #i7983# 456 void SwDoc::PreDelPageDesc(SwPageDesc * pDel) 457 { 458 if (0 == pDel) 459 return; 460 461 // mba: test iteration as clients are removed while iteration 462 SwPageDescHint aHint( aPageDescs[0] ); 463 pDel->CallSwClientNotify( aHint ); 464 465 bool bHasLayout = HasLayout(); 466 if ( pFtnInfo->DependsOn( pDel ) ) 467 { 468 pFtnInfo->ChgPageDesc( aPageDescs[0] ); 469 if ( bHasLayout ) 470 { 471 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 472 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), false)); 473 } 474 } 475 else if ( pEndNoteInfo->DependsOn( pDel ) ) 476 { 477 pEndNoteInfo->ChgPageDesc( aPageDescs[0] ); 478 if ( bHasLayout ) 479 { 480 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 481 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::CheckFtnPageDescs), true)); 482 } 483 } 484 485 for ( sal_uInt16 j = 0; j < aPageDescs.Count(); ++j ) 486 { 487 if ( aPageDescs[j]->GetFollow() == pDel ) 488 { 489 aPageDescs[j]->SetFollow( 0 ); 490 if( bHasLayout ) 491 { 492 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 493 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::AllCheckPageDescs));//swmod 080228 494 } 495 } 496 } 497 } 498 499 // #116530# 500 void SwDoc::BroadcastStyleOperation(String rName, SfxStyleFamily eFamily, 501 sal_uInt16 nOp) 502 { 503 if (pDocShell) 504 { 505 SfxStyleSheetBasePool * pPool = pDocShell->GetStyleSheetPool(); 506 507 if (pPool) 508 { 509 pPool->SetSearchMask(eFamily, SFXSTYLEBIT_ALL ); 510 SfxStyleSheetBase * pBase = pPool->Find(rName); 511 512 if (pBase != NULL) 513 pPool->Broadcast(SfxStyleSheetHint( nOp, *pBase )); 514 } 515 } 516 } 517 518 void SwDoc::DelPageDesc( sal_uInt16 i, sal_Bool bBroadcast ) 519 { 520 ASSERT( i < aPageDescs.Count(), "PageDescs ueberindiziert." ); 521 ASSERT( i != 0, "Default Pagedesc loeschen is nicht." ); 522 if ( i == 0 ) 523 return; 524 525 SwPageDesc *pDel = aPageDescs[i]; 526 527 // -> #116530# 528 if (bBroadcast) 529 BroadcastStyleOperation(pDel->GetName(), SFX_STYLE_FAMILY_PAGE, 530 SFX_STYLESHEET_ERASED); 531 // <- #116530# 532 533 if (GetIDocumentUndoRedo().DoesUndo()) 534 { 535 SwUndo *const pUndo(new SwUndoPageDescDelete(*pDel, this)); 536 GetIDocumentUndoRedo().AppendUndo(pUndo); 537 } 538 539 PreDelPageDesc(pDel); // #i7983# 540 541 aPageDescs.Remove( i ); 542 delete pDel; 543 SetModified(); 544 } 545 546 547 548 /************************************************************************* 549 |* 550 |* SwDoc::MakePageDesc() 551 |* 552 |* Ersterstellung MA 25. Jan. 93 553 |* Letzte Aenderung MA 20. Aug. 93 554 |* 555 |*************************************************************************/ 556 557 sal_uInt16 SwDoc::MakePageDesc( const String &rName, const SwPageDesc *pCpy, 558 sal_Bool bRegardLanguage, sal_Bool bBroadcast) // #116530# 559 { 560 SwPageDesc *pNew; 561 if( pCpy ) 562 { 563 pNew = new SwPageDesc( *pCpy ); 564 pNew->SetName( rName ); 565 if( rName != pCpy->GetName() ) 566 { 567 pNew->SetPoolFmtId( USHRT_MAX ); 568 pNew->SetPoolHelpId( USHRT_MAX ); 569 pNew->SetPoolHlpFileId( UCHAR_MAX ); 570 } 571 } 572 else 573 { 574 pNew = new SwPageDesc( rName, GetDfltFrmFmt(), this ); 575 //Default-Seitenformat einstellen. 576 lcl_DefaultPageFmt( USHRT_MAX, pNew->GetMaster(), pNew->GetLeft() ); 577 578 SvxFrameDirection aFrameDirection = bRegardLanguage ? 579 GetDefaultFrameDirection(GetAppLanguage()) 580 : FRMDIR_HORI_LEFT_TOP; 581 582 pNew->GetMaster().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) ); 583 pNew->GetLeft().SetFmtAttr( SvxFrameDirectionItem(aFrameDirection, RES_FRAMEDIR) ); 584 } 585 aPageDescs.Insert( pNew, aPageDescs.Count() ); 586 587 // -> #116530# 588 if (bBroadcast) 589 BroadcastStyleOperation(rName, SFX_STYLE_FAMILY_PAGE, 590 SFX_STYLESHEET_CREATED); 591 // <- #116530# 592 593 if (GetIDocumentUndoRedo().DoesUndo()) 594 { 595 // #116530# 596 GetIDocumentUndoRedo().AppendUndo(new SwUndoPageDescCreate(pNew, this)); 597 } 598 599 SetModified(); 600 return (aPageDescs.Count()-1); 601 } 602 603 SwPageDesc* SwDoc::FindPageDescByName( const String& rName, sal_uInt16* pPos ) const 604 { 605 SwPageDesc* pRet = 0; 606 if( pPos ) *pPos = USHRT_MAX; 607 608 for( sal_uInt16 n = 0, nEnd = aPageDescs.Count(); n < nEnd; ++n ) 609 if( aPageDescs[ n ]->GetName() == rName ) 610 { 611 pRet = aPageDescs[ n ]; 612 if( pPos ) 613 *pPos = n; 614 break; 615 } 616 return pRet; 617 } 618 619 /****************************************************************************** 620 * Methode : void SwDoc::PrtDataChanged() 621 * Beschreibung: 622 * Erstellt : OK 27.10.94 10:20 623 * Aenderung : MA 26. Mar. 98 624 ******************************************************************************/ 625 626 void SwDoc::PrtDataChanged() 627 { 628 //!!!!!!!! Bei Aenderungen hier bitte ggf. InJobSetup im Sw3io mitpflegen 629 630 // --> FME 2005-01-21 #i41075# 631 ASSERT( get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) || 632 0 != getPrinter( sal_False ), "PrtDataChanged will be called recursive!" ) 633 // <-- 634 SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219 635 SwWait *pWait = 0; 636 sal_Bool bEndAction = sal_False; 637 638 if( GetDocShell() ) 639 GetDocShell()->UpdateFontList(); 640 641 sal_Bool bDraw = sal_True; 642 if ( pTmpRoot ) 643 { 644 ViewShell *pSh = GetCurrentViewShell(); 645 if( !pSh->GetViewOptions()->getBrowseMode() || 646 pSh->GetViewOptions()->IsPrtFormat() ) 647 { 648 if ( GetDocShell() ) 649 pWait = new SwWait( *GetDocShell(), sal_True ); 650 651 pTmpRoot->StartAllAction(); 652 bEndAction = sal_True; 653 654 bDraw = sal_False; 655 if( pDrawModel ) 656 { 657 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) ); 658 pDrawModel->SetRefDevice( getReferenceDevice( false ) ); 659 } 660 661 pFntCache->Flush(); 662 663 std::set<SwRootFrm*> aAllLayouts = GetAllLayouts(); 664 std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::bind2nd(std::mem_fun(&SwRootFrm::InvalidateAllCntnt), INV_SIZE));//swmod 080304 665 666 if ( pSh ) 667 { 668 do 669 { 670 pSh->InitPrt( pPrt ); 671 pSh = (ViewShell*)pSh->GetNext(); 672 } 673 while ( pSh != GetCurrentViewShell() ); 674 } 675 676 } 677 } //swmod 080218 678 if ( bDraw && pDrawModel ) 679 { 680 const sal_Bool bTmpAddExtLeading = get(IDocumentSettingAccess::ADD_EXT_LEADING); 681 if ( bTmpAddExtLeading != pDrawModel->IsAddExtLeading() ) 682 pDrawModel->SetAddExtLeading( bTmpAddExtLeading ); 683 684 OutputDevice* pOutDev = getReferenceDevice( false ); 685 if ( pOutDev != pDrawModel->GetRefDevice() ) 686 pDrawModel->SetRefDevice( pOutDev ); 687 } 688 689 PrtOLENotify( sal_True ); 690 691 if ( bEndAction ) 692 pTmpRoot->EndAllAction(); //swmod 080218 693 delete pWait; 694 } 695 696 //Zur Laufzeit sammeln wir die GlobalNames der Server, die keine 697 //Benachrichtigung zu Druckerwechseln wuenschen. Dadurch sparen wir 698 //das Laden vieler Objekte (gluecklicherweise werden obendrein alle 699 //Fremdobjekte unter einer ID abgebuildet). Init und DeInit vom Array 700 //ist in init.cxx zu finden. 701 extern SvPtrarr *pGlobalOLEExcludeList; 702 703 void SwDoc::PrtOLENotify( sal_Bool bAll ) 704 { 705 SwFEShell *pShell = 0; 706 if ( GetCurrentViewShell() ) 707 { 708 ViewShell *pSh = GetCurrentViewShell(); 709 if ( !pSh->ISA(SwFEShell) ) 710 do 711 { pSh = (ViewShell*)pSh->GetNext(); 712 } while ( !pSh->ISA(SwFEShell) && 713 pSh != GetCurrentViewShell() ); 714 715 if ( pSh->ISA(SwFEShell) ) 716 pShell = (SwFEShell*)pSh; 717 } //swmod 071107//swmod 071225 718 if ( !pShell ) 719 { 720 //Das hat ohne Shell und damit ohne Client keinen Sinn, weil nur darueber 721 //die Kommunikation bezueglich der Groessenaenderung implementiert ist. 722 //Da wir keine Shell haben, merken wir uns diesen unguenstigen 723 //Zustand am Dokument, dies wird dann beim Erzeugen der ersten Shell 724 //nachgeholt. 725 mbOLEPrtNotifyPending = sal_True; 726 if ( bAll ) 727 mbAllOLENotify = sal_True; 728 } 729 else 730 { 731 if ( mbAllOLENotify ) 732 bAll = sal_True; 733 734 mbOLEPrtNotifyPending = mbAllOLENotify = sal_False; 735 736 SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), !bAll ); 737 if ( pNodes ) 738 { 739 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY, 740 0, pNodes->Count(), GetDocShell()); 741 GetCurrentLayout()->StartAllAction(); //swmod 080218 742 743 for( sal_uInt16 i = 0; i < pNodes->Count(); ++i ) 744 { 745 ::SetProgressState( i, GetDocShell() ); 746 747 SwOLENode* pOLENd = (*pNodes)[i]; 748 pOLENd->SetOLESizeInvalid( sal_False ); 749 750 //Ersteinmal die Infos laden und festellen ob das Teil nicht 751 //schon in der Exclude-Liste steht 752 SvGlobalName aName; 753 754 svt::EmbeddedObjectRef& xObj = pOLENd->GetOLEObj().GetObject(); 755 if ( xObj.is() ) 756 aName = SvGlobalName( xObj->getClassID() ); 757 else //Noch nicht geladen 758 { 759 // TODO/LATER: retrieve ClassID of an unloaded object 760 // aName = ???? 761 } 762 763 sal_Bool bFound = sal_False; 764 for ( sal_uInt16 j = 0; 765 j < pGlobalOLEExcludeList->Count() && !bFound; 766 ++j ) 767 { 768 bFound = *(SvGlobalName*)(*pGlobalOLEExcludeList)[j] == 769 aName; 770 } 771 if ( bFound ) 772 continue; 773 774 //Kennen wir nicht, also muss das Objekt geladen werden. 775 //Wenn es keine Benachrichtigung wuenscht 776 if ( xObj.is() ) 777 { 778 //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange 779 /* 780 if ( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xRef->GetMiscStatus()) 781 { 782 if ( pOLENd->GetFrm() ) 783 { 784 xObj->OnDocumentPrinterChanged( pPrt ); 785 pShell->CalcAndSetScale( xObj );//Client erzeugen lassen. 786 } 787 else 788 pOLENd->SetOLESizeInvalid( sal_True ); 789 } 790 else */ 791 pGlobalOLEExcludeList->Insert( 792 new SvGlobalName( aName ), 793 pGlobalOLEExcludeList->Count() ); 794 } 795 } 796 delete pNodes; 797 GetCurrentLayout()->EndAllAction(); //swmod 080218 798 ::EndProgress( GetDocShell() ); 799 } 800 } 801 } 802 803 IMPL_LINK( SwDoc, DoUpdateModifiedOLE, Timer *, ) 804 { 805 SwFEShell* pSh = (SwFEShell*)GetEditShell(); 806 if( pSh ) 807 { 808 mbOLEPrtNotifyPending = mbAllOLENotify = sal_False; 809 810 SwOLENodes *pNodes = SwCntntNode::CreateOLENodesArray( *GetDfltGrfFmtColl(), true ); 811 if( pNodes ) 812 { 813 ::StartProgress( STR_STATSTR_SWGPRTOLENOTIFY, 814 0, pNodes->Count(), GetDocShell()); 815 GetCurrentLayout()->StartAllAction(); //swmod 080218 816 SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR ); 817 818 for( sal_uInt16 i = 0; i < pNodes->Count(); ++i ) 819 { 820 ::SetProgressState( i, GetDocShell() ); 821 822 SwOLENode* pOLENd = (*pNodes)[i]; 823 pOLENd->SetOLESizeInvalid( sal_False ); 824 825 //Kennen wir nicht, also muss das Objekt geladen werden. 826 //Wenn es keine Benachrichtigung wuenscht 827 if( pOLENd->GetOLEObj().GetOleRef().is() ) //Kaputt? 828 { 829 //TODO/LATER: needs MiscStatus for ResizeOnPrinterChange 830 /* 831 if( SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & 832 xRef->GetMiscStatus() ) 833 { 834 if( pOLENd->GetFrm() ) 835 { 836 xRef->OnDocumentPrinterChanged( pPrt ); 837 pSh->CalcAndSetScale( xRef );//Client erzeugen lassen. 838 } 839 else 840 pOLENd->SetOLESizeInvalid( sal_True ); 841 }*/ 842 // repaint it 843 pOLENd->ModifyNotification( &aMsgHint, &aMsgHint ); 844 } 845 } 846 GetCurrentLayout()->EndAllAction(); //swmod 080218 847 ::EndProgress( GetDocShell() ); 848 delete pNodes; 849 } 850 } 851 return 0; 852 } 853 854 sal_Bool SwDoc::FindPageDesc( const String & rName, sal_uInt16 * pFound) 855 { 856 sal_Bool bResult = sal_False; 857 sal_uInt16 nI; 858 for (nI = 0; nI < aPageDescs.Count(); nI++) 859 { 860 if (aPageDescs[nI]->GetName() == rName) 861 { 862 *pFound = nI; 863 bResult = sal_True; 864 break; 865 } 866 } 867 868 return bResult; 869 } 870 871 SwPageDesc * SwDoc::GetPageDesc( const String & rName ) 872 { 873 SwPageDesc * aResult = NULL; 874 875 sal_uInt16 nI; 876 877 if (FindPageDesc(rName, &nI)) 878 aResult = aPageDescs[nI]; 879 880 return aResult; 881 } 882 883 void SwDoc::DelPageDesc( const String & rName, sal_Bool bBroadcast ) // #116530# 884 { 885 sal_uInt16 nI; 886 887 if (FindPageDesc(rName, &nI)) 888 DelPageDesc(nI, bBroadcast); // #116530# 889 } 890 891 void SwDoc::ChgPageDesc( const String & rName, const SwPageDesc & rDesc) 892 { 893 sal_uInt16 nI; 894 895 if (FindPageDesc(rName, &nI)) 896 ChgPageDesc(nI, rDesc); 897 } 898 899 /* 900 * The HTML import cannot resist changing the page descriptions, I don't 901 * know why. This function is meant to check the page descriptors for invalid 902 * values. 903 */ 904 void SwDoc::CheckDefaultPageFmt() 905 { 906 for ( sal_uInt16 i = 0; i < GetPageDescCnt(); ++i ) 907 { 908 SwPageDesc& rDesc = _GetPageDesc( i ); 909 910 SwFrmFmt& rMaster = rDesc.GetMaster(); 911 SwFrmFmt& rLeft = rDesc.GetLeft(); 912 913 const SwFmtFrmSize& rMasterSize = rMaster.GetFrmSize(); 914 const SwFmtFrmSize& rLeftSize = rLeft.GetFrmSize(); 915 916 const bool bSetSize = LONG_MAX == rMasterSize.GetWidth() || 917 LONG_MAX == rMasterSize.GetHeight() || 918 LONG_MAX == rLeftSize.GetWidth() || 919 LONG_MAX == rLeftSize.GetHeight(); 920 921 if ( bSetSize ) 922 lcl_DefaultPageFmt( rDesc.GetPoolFmtId(), rDesc.GetMaster(), rDesc.GetLeft() ); 923 } 924 } 925 926 void SwDoc::SetDefaultPageMode(bool bSquaredPageMode) 927 { 928 if( !bSquaredPageMode == !IsSquaredPageMode() ) 929 return; 930 931 const SwTextGridItem& rGrid = 932 (const SwTextGridItem&)GetDefault( RES_TEXTGRID ); 933 SwTextGridItem aNewGrid = rGrid; 934 aNewGrid.SetSquaredMode(bSquaredPageMode); 935 aNewGrid.Init(); 936 SetDefault(aNewGrid); 937 938 for ( sal_uInt16 i = 0; i < GetPageDescCnt(); ++i ) 939 { 940 SwPageDesc& rDesc = _GetPageDesc( i ); 941 942 SwFrmFmt& rMaster = rDesc.GetMaster(); 943 SwFrmFmt& rLeft = rDesc.GetLeft(); 944 945 SwTextGridItem aGrid((SwTextGridItem&)rMaster.GetFmtAttr(RES_TEXTGRID)); 946 aGrid.SwitchPaperMode( bSquaredPageMode ); 947 rMaster.SetFmtAttr(aGrid); 948 rLeft.SetFmtAttr(aGrid); 949 } 950 } 951 952 sal_Bool SwDoc::IsSquaredPageMode() const 953 { 954 const SwTextGridItem& rGrid = 955 (const SwTextGridItem&)GetDefault( RES_TEXTGRID ); 956 return rGrid.IsSquaredMode(); 957 } 958