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 |* das Gliederungstextobjekt bei den Vorlagen fuer die Gliederungsebenen 266 |* abmelden 267 \************************************************************************/ 268 269 void SdPage::EndListenOutlineText() 270 { 271 SdrObject* pOutlineTextObj = GetPresObj(PRESOBJ_OUTLINE); 272 273 if (pOutlineTextObj) 274 { 275 SdStyleSheetPool* pSPool = (SdStyleSheetPool*)pModel->GetStyleSheetPool(); 276 DBG_ASSERT(pSPool, "StyleSheetPool nicht gefunden"); 277 String aTrueLayoutName(maLayoutName); 278 aTrueLayoutName.Erase( aTrueLayoutName.SearchAscii( SD_LT_SEPARATOR )); 279 List* pOutlineStyles = pSPool->CreateOutlineSheetList(aTrueLayoutName); 280 for (SfxStyleSheet* pSheet = (SfxStyleSheet*)pOutlineStyles->First(); 281 pSheet; 282 pSheet = (SfxStyleSheet*)pOutlineStyles->Next()) 283 { 284 pOutlineTextObj->EndListening(*pSheet); 285 } 286 287 delete pOutlineStyles; 288 } 289 } 290 291 /************************************************************************* 292 |* Neues Modell setzen 293 \************************************************************************/ 294 295 void SdPage::SetModel(SdrModel* pNewModel) 296 { 297 DisconnectLink(); 298 299 // Model umsetzen 300 FmFormPage::SetModel(pNewModel); 301 302 ConnectLink(); 303 } 304 305 /************************************************************************* 306 |* Ist die Seite read-only? 307 \************************************************************************/ 308 309 FASTBOOL SdPage::IsReadOnly() const 310 { 311 return sal_False; 312 } 313 314 /************************************************************************* 315 |* Beim sfx2::LinkManager anmelden 316 \************************************************************************/ 317 318 void SdPage::ConnectLink() 319 { 320 sfx2::LinkManager* pLinkManager = pModel!=NULL ? pModel->GetLinkManager() : NULL; 321 322 if (pLinkManager && !mpPageLink && maFileName.Len() && maBookmarkName.Len() && 323 mePageKind==PK_STANDARD && !IsMasterPage() && 324 ( (SdDrawDocument*) pModel)->IsNewOrLoadCompleted()) 325 { 326 /********************************************************************** 327 * Anmelden 328 * Nur Standardseiten duerfen gelinkt sein 329 **********************************************************************/ 330 ::sd::DrawDocShell* pDocSh = ((SdDrawDocument*) pModel)->GetDocSh(); 331 332 if (!pDocSh || pDocSh->GetMedium()->GetOrigURL() != maFileName) 333 { 334 // Keine Links auf Dokument-eigene Seiten! 335 mpPageLink = new SdPageLink(this, maFileName, maBookmarkName); 336 String aFilterName(SdResId(STR_IMPRESS)); 337 pLinkManager->InsertFileLink(*mpPageLink, OBJECT_CLIENT_FILE, 338 maFileName, &aFilterName, &maBookmarkName); 339 mpPageLink->Connect(); 340 } 341 } 342 } 343 344 345 /************************************************************************* 346 |* Beim sfx2::LinkManager abmelden 347 \************************************************************************/ 348 349 void SdPage::DisconnectLink() 350 { 351 sfx2::LinkManager* pLinkManager = pModel!=NULL ? pModel->GetLinkManager() : NULL; 352 353 if (pLinkManager && mpPageLink) 354 { 355 /********************************************************************** 356 * Abmelden 357 * (Bei Remove wird *pGraphicLink implizit deleted) 358 **********************************************************************/ 359 pLinkManager->Remove(mpPageLink); 360 mpPageLink=NULL; 361 } 362 } 363 364 /************************************************************************* 365 |* Copy-Ctor 366 \************************************************************************/ 367 368 SdPage::SdPage(const SdPage& rSrcPage) 369 : FmFormPage(rSrcPage) 370 , SdrObjUserCall() 371 , mpItems(NULL) 372 { 373 mePageKind = rSrcPage.mePageKind; 374 meAutoLayout = rSrcPage.meAutoLayout; 375 376 SdrObject* pObj = 0; 377 while((pObj = rSrcPage.maPresentationShapeList.getNextShape(pObj)) != 0) 378 InsertPresObj(GetObj(pObj->GetOrdNum()), rSrcPage.GetPresObjKind(pObj)); 379 380 mbSelected = sal_False; 381 mnTransitionType = rSrcPage.mnTransitionType; 382 mnTransitionSubtype = rSrcPage.mnTransitionSubtype; 383 mbTransitionDirection = rSrcPage.mbTransitionDirection; 384 mnTransitionFadeColor = rSrcPage.mnTransitionFadeColor; 385 mfTransitionDuration = rSrcPage.mfTransitionDuration; 386 mePresChange = rSrcPage.mePresChange; 387 mnTime = rSrcPage.mnTime; 388 mbSoundOn = rSrcPage.mbSoundOn; 389 mbExcluded = rSrcPage.mbExcluded; 390 391 maLayoutName = rSrcPage.maLayoutName; 392 maSoundFile = rSrcPage.maSoundFile; 393 mbLoopSound = rSrcPage.mbLoopSound; 394 mbStopSound = rSrcPage.mbStopSound; 395 maCreatedPageName = String(); 396 maFileName = rSrcPage.maFileName; 397 maBookmarkName = rSrcPage.maBookmarkName; 398 mbScaleObjects = rSrcPage.mbScaleObjects; 399 mbBackgroundFullSize = rSrcPage.mbBackgroundFullSize; 400 meCharSet = rSrcPage.meCharSet; 401 mnPaperBin = rSrcPage.mnPaperBin; 402 meOrientation = rSrcPage.meOrientation; 403 404 // header footer 405 setHeaderFooterSettings( rSrcPage.getHeaderFooterSettings() ); 406 407 mpPageLink = NULL; // Wird beim Einfuegen ueber ConnectLink() gesetzt 408 } 409 410 411 412 /************************************************************************* 413 |* Clone 414 \************************************************************************/ 415 416 SdrPage* SdPage::Clone() const 417 { 418 return Clone(NULL); 419 } 420 421 SdrPage* SdPage::Clone(SdrModel* pNewModel) const 422 { 423 DBG_ASSERT( pNewModel == 0, "sd::SdPage::Clone(), new page ignored, please check code! CL" ); 424 (void)pNewModel; 425 426 SdPage* pNewPage = new SdPage(*this); 427 428 cloneAnimations( *pNewPage ); 429 430 // fix user calls for duplicated slide 431 SdrObjListIter aSourceIter( *this, IM_DEEPWITHGROUPS ); 432 SdrObjListIter aTargetIter( *pNewPage, IM_DEEPWITHGROUPS ); 433 434 while( aSourceIter.IsMore() && aTargetIter.IsMore() ) 435 { 436 SdrObject* pSource = aSourceIter.Next(); 437 SdrObject* pTarget = aTargetIter.Next(); 438 439 if( pSource->GetUserCall() ) 440 pTarget->SetUserCall( pNewPage ); 441 } 442 443 return pNewPage; 444 } 445 446 /************************************************************************* 447 |* GetTextStyleSheetForObject 448 \************************************************************************/ 449 450 451 SfxStyleSheet* SdPage::GetTextStyleSheetForObject( SdrObject* pObj ) const 452 { 453 const PresObjKind eKind = ((SdPage*)this)->GetPresObjKind(pObj); 454 if( eKind != PRESOBJ_NONE ) 455 { 456 return ((SdPage*)this)->GetStyleSheetForPresObj(eKind); 457 } 458 459 return FmFormPage::GetTextStyleSheetForObject( pObj ); 460 } 461 462 SfxItemSet* SdPage::getOrCreateItems() 463 { 464 if( mpItems == NULL ) 465 mpItems = new SfxItemSet( pModel->GetItemPool(), SDRATTR_XMLATTRIBUTES, SDRATTR_XMLATTRIBUTES ); 466 467 return mpItems; 468 } 469 470 471 sal_Bool SdPage::setAlienAttributes( const com::sun::star::uno::Any& rAttributes ) 472 { 473 SfxItemSet* pSet = getOrCreateItems(); 474 475 SvXMLAttrContainerItem aAlienAttributes( SDRATTR_XMLATTRIBUTES ); 476 if( aAlienAttributes.PutValue( rAttributes, 0 ) ) 477 { 478 pSet->Put( aAlienAttributes ); 479 return sal_True; 480 } 481 482 return sal_False; 483 } 484 485 void SdPage::getAlienAttributes( com::sun::star::uno::Any& rAttributes ) 486 { 487 const SfxPoolItem* pItem; 488 489 if( (mpItems == NULL) || ( SFX_ITEM_SET != mpItems->GetItemState( SDRATTR_XMLATTRIBUTES, sal_False, &pItem ) ) ) 490 { 491 SvXMLAttrContainerItem aAlienAttributes; 492 aAlienAttributes.QueryValue( rAttributes, 0 ); 493 } 494 else 495 { 496 ((SvXMLAttrContainerItem*)pItem)->QueryValue( rAttributes, 0 ); 497 } 498 } 499 500 void SdPage::RemoveEmptyPresentationObjects() 501 { 502 SdrObjListIter aShapeIter( *this, IM_DEEPWITHGROUPS ); 503 504 SdrObject* pShape; 505 for( pShape = aShapeIter.Next(); pShape; pShape = aShapeIter.Next() ) 506 { 507 if( pShape && pShape->IsEmptyPresObj() ) 508 { 509 RemoveObject( pShape->GetOrdNum() ); 510 SdrObject::Free( pShape ); 511 } 512 513 } 514 } 515 516 sal_Int16 SdPage::getTransitionType (void) const 517 { 518 return mnTransitionType; 519 } 520 521 void SdPage::setTransitionType( sal_Int16 nTransitionType ) 522 { 523 mnTransitionType = nTransitionType; 524 ActionChanged(); 525 } 526 527 sal_Int16 SdPage::getTransitionSubtype (void) const 528 { 529 return mnTransitionSubtype; 530 } 531 532 void SdPage::setTransitionSubtype ( sal_Int16 nTransitionSubtype ) 533 { 534 mnTransitionSubtype = nTransitionSubtype; 535 ActionChanged(); 536 } 537 538 sal_Bool SdPage::getTransitionDirection (void) const 539 { 540 return mbTransitionDirection; 541 } 542 543 void SdPage::setTransitionDirection ( sal_Bool bTransitionbDirection ) 544 { 545 mbTransitionDirection = bTransitionbDirection; 546 ActionChanged(); 547 } 548 549 sal_Int32 SdPage::getTransitionFadeColor (void) const 550 { 551 return mnTransitionFadeColor; 552 } 553 554 void SdPage::setTransitionFadeColor ( sal_Int32 nTransitionFadeColor ) 555 { 556 mnTransitionFadeColor = nTransitionFadeColor; 557 ActionChanged(); 558 } 559 560 double SdPage::getTransitionDuration (void) const 561 { 562 return mfTransitionDuration; 563 } 564 565 void SdPage::setTransitionDuration ( double fTranstionDuration ) 566 { 567 mfTransitionDuration = fTranstionDuration; 568 ActionChanged(); 569 } 570 571 namespace sd { 572 extern void createAnnotation( Reference< XAnnotation >& xAnnotation, SdPage* pPage ); 573 extern SdrUndoAction* CreateUndoInsertOrRemoveAnnotation( const Reference< XAnnotation >& xAnnotation, bool bInsert ); 574 } 575 576 void SdPage::createAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation ) 577 { 578 sd::createAnnotation( xAnnotation, this ); 579 } 580 581 void SdPage::addAnnotation( const Reference< XAnnotation >& xAnnotation, int nIndex ) 582 { 583 if( (nIndex == -1) || (nIndex > (int)maAnnotations.size()) ) 584 { 585 maAnnotations.push_back( xAnnotation ); 586 } 587 else 588 { 589 maAnnotations.insert( maAnnotations.begin() + nIndex, xAnnotation ); 590 } 591 592 if( pModel && pModel->IsUndoEnabled() ) 593 { 594 SdrUndoAction* pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, true ); 595 if( pAction ) 596 pModel->AddUndo( pAction ); 597 } 598 599 SetChanged(); 600 601 if( pModel ) 602 { 603 pModel->SetChanged(); 604 Reference< XInterface > xSource( xAnnotation, UNO_QUERY ); 605 NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAnnotationInserted" ) ), xSource ); 606 } 607 } 608 609 void SdPage::removeAnnotation( const Reference< XAnnotation >& xAnnotation ) 610 { 611 if( pModel && pModel->IsUndoEnabled() ) 612 { 613 SdrUndoAction* pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, false ); 614 if( pAction ) 615 pModel->AddUndo( pAction ); 616 } 617 618 AnnotationVector::iterator iter = std::find( maAnnotations.begin(), maAnnotations.end(), xAnnotation ); 619 if( iter != maAnnotations.end() ) 620 maAnnotations.erase( iter ); 621 622 if( pModel ) 623 { 624 pModel->SetChanged(); 625 Reference< XInterface > xSource( xAnnotation, UNO_QUERY ); 626 NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAnnotationRemoved" ) ), xSource ); 627 } 628 } 629