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_sd.hxx" 26 #include <sfx2/docfile.hxx> 27 #include <vcl/svapp.hxx> 28 #include <editeng/outliner.hxx> 29 #ifndef _SVXLINK_HXX 30 #include <sfx2/linkmgr.hxx> 31 #endif 32 #include <svx/svdotext.hxx> 33 #include <tools/urlobj.hxx> 34 #include <editeng/outlobj.hxx> 35 #include <svl/urihelper.hxx> 36 #include <editeng/xmlcnitm.hxx> 37 #include <svx/svditer.hxx> 38 #include <tools/list.hxx> 39 40 #include "sdresid.hxx" 41 #include "sdpage.hxx" 42 #include "glob.hxx" 43 #include "glob.hrc" 44 #include "drawdoc.hxx" 45 #include "stlpool.hxx" 46 //#include "sdiocmpt.hxx" 47 #include "pglink.hxx" 48 //#include "strmname.h" 49 #include "anminfo.hxx" 50 51 #include "../ui/inc/strings.hrc" 52 #include "../ui/inc/DrawDocShell.hxx" 53 54 // #90477# 55 #include <tools/tenccvt.hxx> 56 #include <svl/itemset.hxx> 57 58 using namespace ::sd; 59 using namespace ::com::sun::star; 60 using namespace ::com::sun::star::uno; 61 using namespace ::com::sun::star::office; 62 63 extern void NotifyDocumentEvent( SdDrawDocument* pDocument, const rtl::OUString& rEventName, const Reference< XInterface >& xSource ); 64 65 /************************************************************************* 66 |* 67 |* SetPresentationLayout, setzt: Layoutnamen, Masterpage-Verkn�pfung und 68 |* Vorlagen fuer Praesentationsobjekte 69 |* 70 |* Vorraussetzungen: - Die Seite muss bereits das richtige Model kennen! 71 |* - Die entsprechende Masterpage muss bereits im Model sein. 72 |* - Die entsprechenden StyleSheets muessen bereits im 73 |* im StyleSheetPool sein. 74 |* 75 |* bReplaceStyleSheets = sal_True : Benannte StyleSheets werden ausgetauscht 76 |* sal_False: Alle StyleSheets werden neu zugewiesen 77 |* 78 |* bSetMasterPage = sal_True : MasterPage suchen und zuweisen 79 |* 80 |* bReverseOrder = sal_False: MasterPages von vorn nach hinten suchen 81 |* sal_True : MasterPages von hinten nach vorn suchen (fuer Undo-Action) 82 |* 83 \************************************************************************/ 84 85 void SdPage::SetPresentationLayout(const String& rLayoutName, 86 sal_Bool bReplaceStyleSheets, 87 sal_Bool bSetMasterPage, 88 sal_Bool bReverseOrder) 89 { 90 /********************************************************************* 91 |* Layoutname der Seite 92 \********************************************************************/ 93 String aOldLayoutName(maLayoutName); // merken 94 maLayoutName = rLayoutName; 95 maLayoutName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR )); 96 maLayoutName += String(SdResId(STR_LAYOUT_OUTLINE)); 97 98 /********************************************************************* 99 |* ggf. Masterpage suchen und setzen 100 \********************************************************************/ 101 if (bSetMasterPage && !IsMasterPage()) 102 { 103 SdPage* pMaster; 104 SdPage* pFoundMaster = 0; 105 sal_uInt16 nMaster = 0; 106 sal_uInt16 nMasterCount = pModel->GetMasterPageCount(); 107 108 if( !bReverseOrder ) 109 { 110 for ( nMaster = 0; nMaster < nMasterCount; nMaster++ ) 111 { 112 pMaster = static_cast<SdPage*>(pModel->GetMasterPage(nMaster)); 113 if (pMaster->GetPageKind() == mePageKind && pMaster->GetLayoutName() == maLayoutName) 114 { 115 pFoundMaster = pMaster; 116 break; 117 } 118 } 119 } 120 else 121 { 122 for ( nMaster = nMasterCount; nMaster > 0; nMaster-- ) 123 { 124 pMaster = static_cast<SdPage*>(pModel->GetMasterPage(nMaster - 1)); 125 if (pMaster->GetPageKind() == mePageKind && pMaster->GetLayoutName() == maLayoutName) 126 { 127 pFoundMaster = pMaster; 128 break; 129 } 130 } 131 } 132 133 DBG_ASSERT(pFoundMaster, "Masterpage for presentation layout not found!"); 134 135 // this should never happen, but we play failsafe here 136 if( pFoundMaster == 0 ) 137 pFoundMaster = static_cast< SdDrawDocument *>(pModel)->GetSdPage( 0, mePageKind ); 138 139 if( pFoundMaster ) 140 TRG_SetMasterPage(*pFoundMaster); 141 } 142 143 /********************************************************************* 144 |* Vorlagen fuer Praesentationsobjekte 145 \********************************************************************/ 146 // Listen mit: 147 // - Vorlagenzeigern fuer Gliederungstextobjekt (alte und neue Vorlagen) 148 // -Replacedaten fuer OutlinerParaObject 149 List aOutlineStyles; 150 List aOldOutlineStyles; 151 List aReplList; 152 sal_Bool bListsFilled = sal_False; 153 154 sal_uLong nObjCount = GetObjCount(); 155 156 for (sal_uLong nObj = 0; nObj < nObjCount; nObj++) 157 { 158 SdrTextObj* pObj = (SdrTextObj*) GetObj(nObj); 159 160 if (pObj->GetObjInventor() == SdrInventor && 161 pObj->GetObjIdentifier() == OBJ_OUTLINETEXT) 162 { 163 if (!bListsFilled || !bReplaceStyleSheets) 164 { 165 String aFullName; 166 String aOldFullName; 167 SfxStyleSheetBase* pSheet = NULL; 168 SfxStyleSheetBasePool* pStShPool = pModel->GetStyleSheetPool(); 169 170 for (sal_Int16 i = -1; i < 9; i++) 171 { 172 aFullName = maLayoutName; 173 aOldFullName = aOldLayoutName; 174 aFullName += sal_Unicode( ' ' ); 175 aFullName += String::CreateFromInt32( (sal_Int32) (i <= 0 ) ? 1 : i + 1); 176 aOldFullName += sal_Unicode( ' ' ); 177 aOldFullName += String::CreateFromInt32( (sal_Int32) (i <= 0 ) ? 1 : i + 1 ); 178 179 pSheet = pStShPool->Find(aOldFullName, SD_STYLE_FAMILY_MASTERPAGE); 180 DBG_ASSERT(pSheet, "alte Gliederungsvorlage nicht gefunden"); 181 aOldOutlineStyles.Insert(pSheet, LIST_APPEND); 182 183 pSheet = pStShPool->Find(aFullName, SD_STYLE_FAMILY_MASTERPAGE); 184 DBG_ASSERT(pSheet, "neue Gliederungsvorlage nicht gefunden"); 185 aOutlineStyles.Insert(pSheet, LIST_APPEND); 186 187 if (bReplaceStyleSheets && pSheet) 188 { 189 // Replace anstatt Set 190 StyleReplaceData* pReplData = new StyleReplaceData; 191 pReplData->nNewFamily = pSheet->GetFamily(); 192 pReplData->nFamily = pSheet->GetFamily(); 193 pReplData->aNewName = aFullName; 194 pReplData->aName = aOldFullName; 195 aReplList.Insert(pReplData, LIST_APPEND); 196 } 197 else 198 { 199 OutlinerParaObject* pOPO = ((SdrTextObj*)pObj)->GetOutlinerParaObject(); 200 201 if( pOPO ) 202 pOPO->SetStyleSheets( i, aFullName, SD_STYLE_FAMILY_MASTERPAGE ); 203 } 204 } 205 206 bListsFilled = sal_True; 207 } 208 209 SfxStyleSheet* pSheet = (SfxStyleSheet*)aOutlineStyles.First(); 210 SfxStyleSheet* pOldSheet = (SfxStyleSheet*)aOldOutlineStyles.First(); 211 while (pSheet) 212 { 213 if (pSheet != pOldSheet) 214 { 215 pObj->EndListening(*pOldSheet); 216 217 if (!pObj->IsListening(*pSheet)) 218 pObj->StartListening(*pSheet); 219 } 220 221 pSheet = (SfxStyleSheet*)aOutlineStyles.Next(); 222 pOldSheet = (SfxStyleSheet*)aOldOutlineStyles.Next(); 223 } 224 225 OutlinerParaObject* pOPO = ((SdrTextObj*)pObj)->GetOutlinerParaObject(); 226 if ( bReplaceStyleSheets && pOPO ) 227 { 228 StyleReplaceData* pReplData = (StyleReplaceData*) aReplList.First(); 229 230 while( pReplData ) 231 { 232 pOPO->ChangeStyleSheets( pReplData->aName, pReplData->nFamily, pReplData->aNewName, pReplData->nNewFamily ); 233 pReplData = (StyleReplaceData*) aReplList.Next(); 234 } 235 } 236 } 237 else if (pObj->GetObjInventor() == SdrInventor && 238 pObj->GetObjIdentifier() == OBJ_TITLETEXT) 239 { 240 // PresObjKind nicht ueber GetPresObjKind() holen, da dort nur 241 // die PresObjListe beruecksichtigt wird. Es sollen aber alle 242 // "Titelobjekte" hier beruecksichtigt werden (Paste aus Clipboard usw.) 243 SfxStyleSheet* pSheet = GetStyleSheetForPresObj(PRESOBJ_TITLE); 244 245 if (pSheet) 246 pObj->SetStyleSheet(pSheet, sal_True); 247 } 248 else 249 { 250 SfxStyleSheet* pSheet = GetStyleSheetForPresObj(GetPresObjKind(pObj)); 251 252 if (pSheet) 253 pObj->SetStyleSheet(pSheet, sal_True); 254 } 255 } 256 257 for (sal_uLong i = 0; i < aReplList.Count(); i++) 258 { 259 delete (StyleReplaceData*) aReplList.GetObject(i); 260 } 261 } 262 263 264 /************************************************************************* 265 |* 266 |* das Gliederungstextobjekt bei den Vorlagen fuer die Gliederungsebenen 267 |* abmelden 268 |* 269 \************************************************************************/ 270 271 void SdPage::EndListenOutlineText() 272 { 273 SdrObject* pOutlineTextObj = GetPresObj(PRESOBJ_OUTLINE); 274 275 if (pOutlineTextObj) 276 { 277 SdStyleSheetPool* pSPool = (SdStyleSheetPool*)pModel->GetStyleSheetPool(); 278 DBG_ASSERT(pSPool, "StyleSheetPool nicht gefunden"); 279 String aTrueLayoutName(maLayoutName); 280 aTrueLayoutName.Erase( aTrueLayoutName.SearchAscii( SD_LT_SEPARATOR )); 281 List* pOutlineStyles = pSPool->CreateOutlineSheetList(aTrueLayoutName); 282 for (SfxStyleSheet* pSheet = (SfxStyleSheet*)pOutlineStyles->First(); 283 pSheet; 284 pSheet = (SfxStyleSheet*)pOutlineStyles->Next()) 285 { 286 pOutlineTextObj->EndListening(*pSheet); 287 } 288 289 delete pOutlineStyles; 290 } 291 } 292 293 /************************************************************************* 294 |* 295 |* Neues Model setzen 296 |* 297 \************************************************************************/ 298 299 void SdPage::SetModel(SdrModel* pNewModel) 300 { 301 DisconnectLink(); 302 303 // Model umsetzen 304 FmFormPage::SetModel(pNewModel); 305 306 ConnectLink(); 307 } 308 309 /************************************************************************* 310 |* 311 |* Ist die Seite read-only? 312 |* 313 \************************************************************************/ 314 315 FASTBOOL SdPage::IsReadOnly() const 316 { 317 return sal_False; 318 } 319 320 /************************************************************************* 321 |* 322 |* Beim sfx2::LinkManager anmelden 323 |* 324 \************************************************************************/ 325 326 void SdPage::ConnectLink() 327 { 328 sfx2::LinkManager* pLinkManager = pModel!=NULL ? pModel->GetLinkManager() : NULL; 329 330 if (pLinkManager && !mpPageLink && maFileName.Len() && maBookmarkName.Len() && 331 mePageKind==PK_STANDARD && !IsMasterPage() && 332 ( (SdDrawDocument*) pModel)->IsNewOrLoadCompleted()) 333 { 334 /********************************************************************** 335 * Anmelden 336 * Nur Standardseiten duerfen gelinkt sein 337 **********************************************************************/ 338 ::sd::DrawDocShell* pDocSh = ((SdDrawDocument*) pModel)->GetDocSh(); 339 340 if (!pDocSh || pDocSh->GetMedium()->GetOrigURL() != maFileName) 341 { 342 // Keine Links auf Dokument-eigene Seiten! 343 mpPageLink = new SdPageLink(this, maFileName, maBookmarkName); 344 String aFilterName(SdResId(STR_IMPRESS)); 345 pLinkManager->InsertFileLink(*mpPageLink, OBJECT_CLIENT_FILE, 346 maFileName, &aFilterName, &maBookmarkName); 347 mpPageLink->Connect(); 348 } 349 } 350 } 351 352 353 /************************************************************************* 354 |* 355 |* Beim sfx2::LinkManager abmelden 356 |* 357 \************************************************************************/ 358 359 void SdPage::DisconnectLink() 360 { 361 sfx2::LinkManager* pLinkManager = pModel!=NULL ? pModel->GetLinkManager() : NULL; 362 363 if (pLinkManager && mpPageLink) 364 { 365 /********************************************************************** 366 * Abmelden 367 * (Bei Remove wird *pGraphicLink implizit deleted) 368 **********************************************************************/ 369 pLinkManager->Remove(mpPageLink); 370 mpPageLink=NULL; 371 } 372 } 373 374 /************************************************************************* 375 |* 376 |* Copy-Ctor 377 |* 378 \************************************************************************/ 379 380 SdPage::SdPage(const SdPage& rSrcPage) 381 : FmFormPage(rSrcPage) 382 , SdrObjUserCall() 383 , mpItems(NULL) 384 { 385 mePageKind = rSrcPage.mePageKind; 386 meAutoLayout = rSrcPage.meAutoLayout; 387 388 SdrObject* pObj = 0; 389 while((pObj = rSrcPage.maPresentationShapeList.getNextShape(pObj)) != 0) 390 InsertPresObj(GetObj(pObj->GetOrdNum()), rSrcPage.GetPresObjKind(pObj)); 391 392 mbSelected = sal_False; 393 mnTransitionType = rSrcPage.mnTransitionType; 394 mnTransitionSubtype = rSrcPage.mnTransitionSubtype; 395 mbTransitionDirection = rSrcPage.mbTransitionDirection; 396 mnTransitionFadeColor = rSrcPage.mnTransitionFadeColor; 397 mfTransitionDuration = rSrcPage.mfTransitionDuration; 398 mePresChange = rSrcPage.mePresChange; 399 mnTime = rSrcPage.mnTime; 400 mbSoundOn = rSrcPage.mbSoundOn; 401 mbExcluded = rSrcPage.mbExcluded; 402 403 maLayoutName = rSrcPage.maLayoutName; 404 maSoundFile = rSrcPage.maSoundFile; 405 mbLoopSound = rSrcPage.mbLoopSound; 406 mbStopSound = rSrcPage.mbStopSound; 407 maCreatedPageName = String(); 408 maFileName = rSrcPage.maFileName; 409 maBookmarkName = rSrcPage.maBookmarkName; 410 mbScaleObjects = rSrcPage.mbScaleObjects; 411 mbBackgroundFullSize = rSrcPage.mbBackgroundFullSize; 412 meCharSet = rSrcPage.meCharSet; 413 mnPaperBin = rSrcPage.mnPaperBin; 414 meOrientation = rSrcPage.meOrientation; 415 416 // header footer 417 setHeaderFooterSettings( rSrcPage.getHeaderFooterSettings() ); 418 419 mpPageLink = NULL; // Wird beim Einfuegen ueber ConnectLink() gesetzt 420 } 421 422 423 424 /************************************************************************* 425 |* 426 |* Clone 427 |* 428 \************************************************************************/ 429 430 SdrPage* SdPage::Clone() const 431 { 432 return Clone(NULL); 433 } 434 435 SdrPage* SdPage::Clone(SdrModel* pNewModel) const 436 { 437 DBG_ASSERT( pNewModel == 0, "sd::SdPage::Clone(), new page ignored, please check code! CL" ); 438 (void)pNewModel; 439 440 SdPage* pNewPage = new SdPage(*this); 441 442 cloneAnimations( *pNewPage ); 443 444 // fix user calls for duplicated slide 445 SdrObjListIter aSourceIter( *this, IM_DEEPWITHGROUPS ); 446 SdrObjListIter aTargetIter( *pNewPage, IM_DEEPWITHGROUPS ); 447 448 while( aSourceIter.IsMore() && aTargetIter.IsMore() ) 449 { 450 SdrObject* pSource = aSourceIter.Next(); 451 SdrObject* pTarget = aTargetIter.Next(); 452 453 if( pSource->GetUserCall() ) 454 pTarget->SetUserCall( pNewPage ); 455 } 456 457 return pNewPage; 458 } 459 460 /************************************************************************* 461 |* 462 |* GetTextStyleSheetForObject 463 |* 464 \************************************************************************/ 465 466 467 SfxStyleSheet* SdPage::GetTextStyleSheetForObject( SdrObject* pObj ) const 468 { 469 const PresObjKind eKind = ((SdPage*)this)->GetPresObjKind(pObj); 470 if( eKind != PRESOBJ_NONE ) 471 { 472 return ((SdPage*)this)->GetStyleSheetForPresObj(eKind); 473 } 474 475 return FmFormPage::GetTextStyleSheetForObject( pObj ); 476 } 477 478 SfxItemSet* SdPage::getOrCreateItems() 479 { 480 if( mpItems == NULL ) 481 mpItems = new SfxItemSet( pModel->GetItemPool(), SDRATTR_XMLATTRIBUTES, SDRATTR_XMLATTRIBUTES ); 482 483 return mpItems; 484 } 485 486 487 sal_Bool SdPage::setAlienAttributes( const com::sun::star::uno::Any& rAttributes ) 488 { 489 SfxItemSet* pSet = getOrCreateItems(); 490 491 SvXMLAttrContainerItem aAlienAttributes( SDRATTR_XMLATTRIBUTES ); 492 if( aAlienAttributes.PutValue( rAttributes, 0 ) ) 493 { 494 pSet->Put( aAlienAttributes ); 495 return sal_True; 496 } 497 498 return sal_False; 499 } 500 501 void SdPage::getAlienAttributes( com::sun::star::uno::Any& rAttributes ) 502 { 503 const SfxPoolItem* pItem; 504 505 if( (mpItems == NULL) || ( SFX_ITEM_SET != mpItems->GetItemState( SDRATTR_XMLATTRIBUTES, sal_False, &pItem ) ) ) 506 { 507 SvXMLAttrContainerItem aAlienAttributes; 508 aAlienAttributes.QueryValue( rAttributes, 0 ); 509 } 510 else 511 { 512 ((SvXMLAttrContainerItem*)pItem)->QueryValue( rAttributes, 0 ); 513 } 514 } 515 516 void SdPage::RemoveEmptyPresentationObjects() 517 { 518 SdrObjListIter aShapeIter( *this, IM_DEEPWITHGROUPS ); 519 520 SdrObject* pShape; 521 for( pShape = aShapeIter.Next(); pShape; pShape = aShapeIter.Next() ) 522 { 523 if( pShape && pShape->IsEmptyPresObj() ) 524 { 525 RemoveObject( pShape->GetOrdNum() ); 526 SdrObject::Free( pShape ); 527 } 528 529 } 530 } 531 532 sal_Int16 SdPage::getTransitionType (void) const 533 { 534 return mnTransitionType; 535 } 536 537 void SdPage::setTransitionType( sal_Int16 nTransitionType ) 538 { 539 mnTransitionType = nTransitionType; 540 ActionChanged(); 541 } 542 543 sal_Int16 SdPage::getTransitionSubtype (void) const 544 { 545 return mnTransitionSubtype; 546 } 547 548 void SdPage::setTransitionSubtype ( sal_Int16 nTransitionSubtype ) 549 { 550 mnTransitionSubtype = nTransitionSubtype; 551 ActionChanged(); 552 } 553 554 sal_Bool SdPage::getTransitionDirection (void) const 555 { 556 return mbTransitionDirection; 557 } 558 559 void SdPage::setTransitionDirection ( sal_Bool bTransitionbDirection ) 560 { 561 mbTransitionDirection = bTransitionbDirection; 562 ActionChanged(); 563 } 564 565 sal_Int32 SdPage::getTransitionFadeColor (void) const 566 { 567 return mnTransitionFadeColor; 568 } 569 570 void SdPage::setTransitionFadeColor ( sal_Int32 nTransitionFadeColor ) 571 { 572 mnTransitionFadeColor = nTransitionFadeColor; 573 ActionChanged(); 574 } 575 576 double SdPage::getTransitionDuration (void) const 577 { 578 return mfTransitionDuration; 579 } 580 581 void SdPage::setTransitionDuration ( double fTranstionDuration ) 582 { 583 mfTransitionDuration = fTranstionDuration; 584 ActionChanged(); 585 } 586 587 namespace sd { 588 extern void createAnnotation( Reference< XAnnotation >& xAnnotation, SdPage* pPage ); 589 extern SdrUndoAction* CreateUndoInsertOrRemoveAnnotation( const Reference< XAnnotation >& xAnnotation, bool bInsert ); 590 } 591 592 void SdPage::createAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation ) 593 { 594 sd::createAnnotation( xAnnotation, this ); 595 } 596 597 void SdPage::addAnnotation( const Reference< XAnnotation >& xAnnotation, int nIndex ) 598 { 599 if( (nIndex == -1) || (nIndex > (int)maAnnotations.size()) ) 600 { 601 maAnnotations.push_back( xAnnotation ); 602 } 603 else 604 { 605 maAnnotations.insert( maAnnotations.begin() + nIndex, xAnnotation ); 606 } 607 608 if( pModel && pModel->IsUndoEnabled() ) 609 { 610 SdrUndoAction* pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, true ); 611 if( pAction ) 612 pModel->AddUndo( pAction ); 613 } 614 615 SetChanged(); 616 617 if( pModel ) 618 { 619 pModel->SetChanged(); 620 Reference< XInterface > xSource( xAnnotation, UNO_QUERY ); 621 NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAnnotationInserted" ) ), xSource ); 622 } 623 } 624 625 void SdPage::removeAnnotation( const Reference< XAnnotation >& xAnnotation ) 626 { 627 if( pModel && pModel->IsUndoEnabled() ) 628 { 629 SdrUndoAction* pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, false ); 630 if( pAction ) 631 pModel->AddUndo( pAction ); 632 } 633 634 AnnotationVector::iterator iter = std::find( maAnnotations.begin(), maAnnotations.end(), xAnnotation ); 635 if( iter != maAnnotations.end() ) 636 maAnnotations.erase( iter ); 637 638 if( pModel ) 639 { 640 pModel->SetChanged(); 641 Reference< XInterface > xSource( xAnnotation, UNO_QUERY ); 642 NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAnnotationRemoved" ) ), xSource ); 643 } 644 } 645